1 |
commit: 24e0750a927f29bdfd935e68b17c3be31c92a932 |
2 |
Author: Stephan Hartmann <stha09 <AT> googlemail <DOT> com> |
3 |
AuthorDate: Thu Apr 30 18:03:53 2020 +0000 |
4 |
Commit: Mike Gilbert <floppym <AT> gentoo <DOT> org> |
5 |
CommitDate: Fri May 1 15:31:37 2020 +0000 |
6 |
URL: https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=24e0750a |
7 |
|
8 |
www-client/chromium: beta channel bump to 83.0.4103.34 |
9 |
|
10 |
Package-Manager: Portage-2.3.89, Repoman-2.3.20 |
11 |
Signed-off-by: Stephan Hartmann <stha09 <AT> googlemail.com> |
12 |
Signed-off-by: Mike Gilbert <floppym <AT> gentoo.org> |
13 |
|
14 |
www-client/chromium/Manifest | 2 +- |
15 |
...4103.23.ebuild => chromium-83.0.4103.34.ebuild} | 8 +- |
16 |
.../files/chromium-83-gcc-serviceworker.patch | 130 ++++++++++++++++ |
17 |
www-client/chromium/files/chromium-83-icu67.patch | 170 +++++++++++++++++++++ |
18 |
4 files changed, 306 insertions(+), 4 deletions(-) |
19 |
|
20 |
diff --git a/www-client/chromium/Manifest b/www-client/chromium/Manifest |
21 |
index c9f5ef3ccd4..3dd02cf00c3 100644 |
22 |
--- a/www-client/chromium/Manifest |
23 |
+++ b/www-client/chromium/Manifest |
24 |
@@ -1,3 +1,3 @@ |
25 |
DIST chromium-81.0.4044.129.tar.xz 785978416 BLAKE2B 5af9ab9e17bbc237f5a254b98cb27b998021d5c95b5da4d6de25c3fb234fea609f8a9173f3ac75eee208b8c88c5d39d9cf1ec39ebc8d436cf8aafee31e8f32c1 SHA512 93dfc5c1050bc226b836721d422a8d98a183fff81e91f55477dce0c650d35a95aeb89c810bea6e07ffb948ee62e8e150c8b8c5bad4658fcc215de05a681b064a |
26 |
-DIST chromium-83.0.4103.23.tar.xz 802566932 BLAKE2B 00c9105a9b5e9cebc8adeb8a61b4491f0ca7cc95da9595506c77d556c0ee07074da0da506831bec1b390a39c7535220ab5c6d06ce784e6b20d2694f94d3b0a76 SHA512 08a50372570aa9da5fb9ccc6dfc3d949e84cb401d62d650132aa4edea2b1658fb56a81854fde11690d040e3b36b9d20da1ad7f83e47ffca77893ab57620c2a3e |
27 |
+DIST chromium-83.0.4103.34.tar.xz 802525184 BLAKE2B d5e47c96642fb9344fe43a582d035f507b714565c01b6bacbf1cd4fdb3537db28ae0e54a47bbd7f47ad4d00960ee9e40d9a10522262cba4063f95501225fce75 SHA512 467006d3b3093b078569c0ead9203e66cfd83ad14ed95a07b5f83e49451a0e9f4506b3ce35c97106b4540b55484d6cd33afbacf92385ace261e78d5c1cc0188e |
28 |
DIST setuptools-44.1.0.zip 858569 BLAKE2B f59f154e121502a731e51294ccd293d60ffccadacf51e23b53bf7ceba38858948b86783238061136c827ac3373ea7ea8e6253d4bb53f3f1dd69284568ec65a68 SHA512 4dfb0f42d334b835758e865a26ecd1e725711fa2b9c38ddc273b8b3849fba04527bc97436d11ba1e98f1a42922aa0f0b9032e32998273c705fac6e10735eacbf |
29 |
|
30 |
diff --git a/www-client/chromium/chromium-83.0.4103.23.ebuild b/www-client/chromium/chromium-83.0.4103.34.ebuild |
31 |
similarity index 99% |
32 |
rename from www-client/chromium/chromium-83.0.4103.23.ebuild |
33 |
rename to www-client/chromium/chromium-83.0.4103.34.ebuild |
34 |
index 2056dda0889..2cb862a2cb9 100644 |
35 |
--- a/www-client/chromium/chromium-83.0.4103.23.ebuild |
36 |
+++ b/www-client/chromium/chromium-83.0.4103.34.ebuild |
37 |
@@ -103,8 +103,8 @@ BDEPEND=" |
38 |
) |
39 |
" |
40 |
|
41 |
-: ${CHROMIUM_FORCE_CLANG=yes} |
42 |
-: ${CHROMIUM_FORCE_LIBCXX=yes} |
43 |
+: ${CHROMIUM_FORCE_CLANG=no} |
44 |
+: ${CHROMIUM_FORCE_LIBCXX=no} |
45 |
|
46 |
if [[ ${CHROMIUM_FORCE_CLANG} == yes ]]; then |
47 |
BDEPEND+=" >=sys-devel/clang-9" |
48 |
@@ -123,7 +123,7 @@ else |
49 |
dev-libs/libxslt:= |
50 |
>=dev-libs/re2-0.2019.08.01:= |
51 |
>=media-libs/openh264-1.6.0:= |
52 |
- system-icu? ( >=dev-libs/icu-65:= ) |
53 |
+ system-icu? ( >=dev-libs/icu-67.1:= ) |
54 |
" |
55 |
RDEPEND+="${COMMON_DEPEND}" |
56 |
DEPEND+="${COMMON_DEPEND}" |
57 |
@@ -178,7 +178,9 @@ PATCHES=( |
58 |
"${FILESDIR}/chromium-83-gcc-include.patch" |
59 |
"${FILESDIR}/chromium-83-gcc-permissive.patch" |
60 |
"${FILESDIR}/chromium-83-gcc-iterator.patch" |
61 |
+ "${FILESDIR}/chromium-83-gcc-serviceworker.patch" |
62 |
"${FILESDIR}/chromium-83-gcc-10.patch" |
63 |
+ "${FILESDIR}/chromium-83-icu67.patch" |
64 |
) |
65 |
|
66 |
pre_build_checks() { |
67 |
|
68 |
diff --git a/www-client/chromium/files/chromium-83-gcc-serviceworker.patch b/www-client/chromium/files/chromium-83-gcc-serviceworker.patch |
69 |
new file mode 100644 |
70 |
index 00000000000..a836e7fc533 |
71 |
--- /dev/null |
72 |
+++ b/www-client/chromium/files/chromium-83-gcc-serviceworker.patch |
73 |
@@ -0,0 +1,130 @@ |
74 |
+From 0914a38252f205fc04fa50e858b24fa5f535ab11 Mon Sep 17 00:00:00 2001 |
75 |
+From: Hiroki Nakagawa <nhiroki@××××××××.org> |
76 |
+Date: Wed, 29 Apr 2020 11:46:54 +0900 |
77 |
+Subject: [PATCH] ServiceWorker: Avoid double destruction of ServiceWorkerObjectHost on connection error |
78 |
+ |
79 |
+This CL avoids the case where ServiceWorkerObjectHost is destroyed twice |
80 |
+on ServiceWorkerObjectHost::OnConnectionError() when Chromium is built |
81 |
+with the GCC build toolchain. |
82 |
+ |
83 |
+> How does the issue happen? |
84 |
+ |
85 |
+ServiceWorkerObjectHost has a cyclic reference like this: |
86 |
+ |
87 |
+ServiceWorkerObjectHost |
88 |
+ --([1] scoped_refptr)--> ServiceWorkerVersion |
89 |
+ --([2] std::unique_ptr)--> ServiceWorkerProviderHost |
90 |
+ --([3] std::unique_ptr)--> ServiceWorkerContainerHost |
91 |
+ --([4] std::unique_ptr)--> ServiceWorkerObjectHost |
92 |
+ |
93 |
+Note that ServiceWorkerContainerHost manages ServiceWorkerObjectHost in |
94 |
+map<int64_t version_id, std::unique_ptr<ServiceWorkerObjectHost>>. |
95 |
+ |
96 |
+When ServiceWorkerObjectHost::OnConnectionError() is called, the |
97 |
+function removes the reference [4] from the map, and destroys |
98 |
+ServiceWorkerObjectHost. If the object host has the last reference [1] |
99 |
+to ServiceWorkerVersion, the destruction also cuts off the references |
100 |
+[2] and [3], and destroys ServiceWorkerProviderHost and |
101 |
+ServiceWorkerContainerHost. |
102 |
+ |
103 |
+This seems to work well on the Chromium's default toolchain, but not |
104 |
+work on the GCC toolchain. According to the report, destruction of |
105 |
+ServiceWorkerContainerHost happens while the map owned by the container |
106 |
+host is erasing the ServiceWorkerObjectHost, and this results in crash |
107 |
+due to double destruction of the object host. |
108 |
+ |
109 |
+I don't know the reason why this happens only on the GCC toolchain, but |
110 |
+I suspect the order of object destruction on std::map::erase() could be |
111 |
+different depending on the toolchains. |
112 |
+ |
113 |
+> How does this CL fix this? |
114 |
+ |
115 |
+The ideal fix is to redesign the ownership model of |
116 |
+ServiceWorkerVersion, but it's not feasible in the short term. |
117 |
+ |
118 |
+Instead, this CL avoids destruction of ServiceWorkerObjectHost on |
119 |
+std::map::erase(). The new code takes the ownership of the object host |
120 |
+from the map first, and then erases the entry from the map. This |
121 |
+separates timings to erase the map entry and to destroy the object host, |
122 |
+so the crash should no longer happen. |
123 |
+ |
124 |
+Bug: 1056598 |
125 |
+Change-Id: Id30654cb575bc557c42044d6f0c6f1f9bfaed613 |
126 |
+--- |
127 |
+ |
128 |
+diff --git a/content/browser/service_worker/service_worker_container_host.cc b/content/browser/service_worker/service_worker_container_host.cc |
129 |
+index c631bcd..ff917f8 100644 |
130 |
+--- a/content/browser/service_worker/service_worker_container_host.cc |
131 |
++++ b/content/browser/service_worker/service_worker_container_host.cc |
132 |
+@@ -717,6 +717,16 @@ |
133 |
+ int64_t version_id) { |
134 |
+ DCHECK_CURRENTLY_ON(ServiceWorkerContext::GetCoreThreadId()); |
135 |
+ DCHECK(base::Contains(service_worker_object_hosts_, version_id)); |
136 |
++ |
137 |
++ // ServiceWorkerObjectHost to be deleted may have the last reference to |
138 |
++ // ServiceWorkerVersion that indirectly owns this ServiceWorkerContainerHost. |
139 |
++ // If we erase the object host directly from the map, |this| could be deleted |
140 |
++ // during the map operation and may crash. To avoid the case, we take the |
141 |
++ // ownership of the object host from the map first, and then erase the entry |
142 |
++ // from the map. See https://crbug.com/1056598 for details. |
143 |
++ std::unique_ptr<ServiceWorkerObjectHost> to_be_deleted = |
144 |
++ std::move(service_worker_object_hosts_[version_id]); |
145 |
++ DCHECK(to_be_deleted); |
146 |
+ service_worker_object_hosts_.erase(version_id); |
147 |
+ } |
148 |
+ |
149 |
+diff --git a/content/browser/service_worker/service_worker_object_host_unittest.cc b/content/browser/service_worker/service_worker_object_host_unittest.cc |
150 |
+index 238cb8b..f60c7a2 100644 |
151 |
+--- a/content/browser/service_worker/service_worker_object_host_unittest.cc |
152 |
++++ b/content/browser/service_worker/service_worker_object_host_unittest.cc |
153 |
+@@ -200,6 +200,19 @@ |
154 |
+ return registration_info; |
155 |
+ } |
156 |
+ |
157 |
++ void CallOnConnectionError(ServiceWorkerContainerHost* container_host, |
158 |
++ int64_t version_id) { |
159 |
++ // ServiceWorkerObjectHost has the last reference to the version. |
160 |
++ ServiceWorkerObjectHost* object_host = |
161 |
++ GetServiceWorkerObjectHost(container_host, version_id); |
162 |
++ EXPECT_TRUE(object_host->version_->HasOneRef()); |
163 |
++ |
164 |
++ // Make sure that OnConnectionError induces destruction of the version and |
165 |
++ // the object host. |
166 |
++ object_host->receivers_.Clear(); |
167 |
++ object_host->OnConnectionError(); |
168 |
++ } |
169 |
++ |
170 |
+ BrowserTaskEnvironment task_environment_; |
171 |
+ std::unique_ptr<EmbeddedWorkerTestHelper> helper_; |
172 |
+ scoped_refptr<ServiceWorkerRegistration> registration_; |
173 |
+@@ -409,5 +422,30 @@ |
174 |
+ events[0]->source_info_for_client->client_type); |
175 |
+ } |
176 |
+ |
177 |
++// This is a regression test for https://crbug.com/1056598. |
178 |
++TEST_F(ServiceWorkerObjectHostTest, OnConnectionError) { |
179 |
++ const GURL scope("https://www.example.com/"); |
180 |
++ const GURL script_url("https://www.example.com/service_worker.js"); |
181 |
++ Initialize(std::make_unique<EmbeddedWorkerTestHelper>(base::FilePath())); |
182 |
++ SetUpRegistration(scope, script_url); |
183 |
++ |
184 |
++ // Create the provider host. |
185 |
++ ASSERT_EQ(blink::ServiceWorkerStatusCode::kOk, |
186 |
++ StartServiceWorker(version_.get())); |
187 |
++ |
188 |
++ // Set up the case where the last reference to the version is owned by the |
189 |
++ // service worker object host. |
190 |
++ ServiceWorkerContainerHost* container_host = |
191 |
++ version_->provider_host()->container_host(); |
192 |
++ ServiceWorkerVersion* version_rawptr = version_.get(); |
193 |
++ version_ = nullptr; |
194 |
++ ASSERT_TRUE(version_rawptr->HasOneRef()); |
195 |
++ |
196 |
++ // Simulate the connection error that induces the object host destruction. |
197 |
++ // This shouldn't crash. |
198 |
++ CallOnConnectionError(container_host, version_rawptr->version_id()); |
199 |
++ base::RunLoop().RunUntilIdle(); |
200 |
++} |
201 |
++ |
202 |
+ } // namespace service_worker_object_host_unittest |
203 |
+ } // namespace content |
204 |
|
205 |
diff --git a/www-client/chromium/files/chromium-83-icu67.patch b/www-client/chromium/files/chromium-83-icu67.patch |
206 |
new file mode 100644 |
207 |
index 00000000000..d45d9e810a4 |
208 |
--- /dev/null |
209 |
+++ b/www-client/chromium/files/chromium-83-icu67.patch |
210 |
@@ -0,0 +1,170 @@ |
211 |
+From 3f8dc4b2e5baf77b463334c769af85b79d8c1463 Mon Sep 17 00:00:00 2001 |
212 |
+From: Frank Tang <ftang@××××××××.org> |
213 |
+Date: Fri, 03 Apr 2020 23:13:54 -0700 |
214 |
+Subject: [PATCH] [intl] Remove soon-to-be removed getAllFieldPositions |
215 |
+ |
216 |
+Needed to land ICU67.1 soon. |
217 |
+ |
218 |
+Bug: v8:10393 |
219 |
+Change-Id: I3c7737ca600d6ccfdc46ffaddfb318ce60bc7618 |
220 |
+Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2136489 |
221 |
+Reviewed-by: Jakob Kummerow <jkummerow@××××××××.org> |
222 |
+Commit-Queue: Frank Tang <ftang@××××××××.org> |
223 |
+Cr-Commit-Position: refs/heads/master@{#67027} |
224 |
+--- |
225 |
+ |
226 |
+diff --git a/v8/src/objects/js-number-format.cc b/v8/src/objects/js-number-format.cc |
227 |
+index ad831c5..bcd4403 100644 |
228 |
+--- a/v8/src/objects/js-number-format.cc |
229 |
++++ b/v8/src/objects/js-number-format.cc |
230 |
+@@ -1241,44 +1241,33 @@ |
231 |
+ } |
232 |
+ |
233 |
+ namespace { |
234 |
+-Maybe<icu::UnicodeString> IcuFormatNumber( |
235 |
++Maybe<bool> IcuFormatNumber( |
236 |
+ Isolate* isolate, |
237 |
+ const icu::number::LocalizedNumberFormatter& number_format, |
238 |
+- Handle<Object> numeric_obj, icu::FieldPositionIterator* fp_iter) { |
239 |
++ Handle<Object> numeric_obj, icu::number::FormattedNumber* formatted) { |
240 |
+ // If it is BigInt, handle it differently. |
241 |
+ UErrorCode status = U_ZERO_ERROR; |
242 |
+- icu::number::FormattedNumber formatted; |
243 |
+ if (numeric_obj->IsBigInt()) { |
244 |
+ Handle<BigInt> big_int = Handle<BigInt>::cast(numeric_obj); |
245 |
+ Handle<String> big_int_string; |
246 |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE(isolate, big_int_string, |
247 |
+ BigInt::ToString(isolate, big_int), |
248 |
+- Nothing<icu::UnicodeString>()); |
249 |
+- formatted = number_format.formatDecimal( |
250 |
++ Nothing<bool>()); |
251 |
++ *formatted = number_format.formatDecimal( |
252 |
+ {big_int_string->ToCString().get(), big_int_string->length()}, status); |
253 |
+ } else { |
254 |
+ double number = numeric_obj->IsNaN() |
255 |
+ ? std::numeric_limits<double>::quiet_NaN() |
256 |
+ : numeric_obj->Number(); |
257 |
+- formatted = number_format.formatDouble(number, status); |
258 |
++ *formatted = number_format.formatDouble(number, status); |
259 |
+ } |
260 |
+ if (U_FAILURE(status)) { |
261 |
+ // This happen because of icu data trimming trim out "unit". |
262 |
+ // See https://bugs.chromium.org/p/v8/issues/detail?id=8641 |
263 |
+- THROW_NEW_ERROR_RETURN_VALUE(isolate, |
264 |
+- NewTypeError(MessageTemplate::kIcuError), |
265 |
+- Nothing<icu::UnicodeString>()); |
266 |
++ THROW_NEW_ERROR_RETURN_VALUE( |
267 |
++ isolate, NewTypeError(MessageTemplate::kIcuError), Nothing<bool>()); |
268 |
+ } |
269 |
+- if (fp_iter) { |
270 |
+- formatted.getAllFieldPositions(*fp_iter, status); |
271 |
+- } |
272 |
+- icu::UnicodeString result = formatted.toString(status); |
273 |
+- if (U_FAILURE(status)) { |
274 |
+- THROW_NEW_ERROR_RETURN_VALUE(isolate, |
275 |
+- NewTypeError(MessageTemplate::kIcuError), |
276 |
+- Nothing<icu::UnicodeString>()); |
277 |
+- } |
278 |
+- return Just(result); |
279 |
++ return Just(true); |
280 |
+ } |
281 |
+ |
282 |
+ } // namespace |
283 |
+@@ -1289,10 +1278,16 @@ |
284 |
+ Handle<Object> numeric_obj) { |
285 |
+ DCHECK(numeric_obj->IsNumeric()); |
286 |
+ |
287 |
+- Maybe<icu::UnicodeString> maybe_format = |
288 |
+- IcuFormatNumber(isolate, number_format, numeric_obj, nullptr); |
289 |
++ icu::number::FormattedNumber formatted; |
290 |
++ Maybe<bool> maybe_format = |
291 |
++ IcuFormatNumber(isolate, number_format, numeric_obj, &formatted); |
292 |
+ MAYBE_RETURN(maybe_format, Handle<String>()); |
293 |
+- return Intl::ToString(isolate, maybe_format.FromJust()); |
294 |
++ UErrorCode status = U_ZERO_ERROR; |
295 |
++ icu::UnicodeString result = formatted.toString(status); |
296 |
++ if (U_FAILURE(status)) { |
297 |
++ THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError), String); |
298 |
++ } |
299 |
++ return Intl::ToString(isolate, result); |
300 |
+ } |
301 |
+ |
302 |
+ namespace { |
303 |
+@@ -1405,12 +1400,18 @@ |
304 |
+ } |
305 |
+ |
306 |
+ namespace { |
307 |
+-Maybe<int> ConstructParts(Isolate* isolate, const icu::UnicodeString& formatted, |
308 |
+- icu::FieldPositionIterator* fp_iter, |
309 |
++Maybe<int> ConstructParts(Isolate* isolate, |
310 |
++ icu::number::FormattedNumber* formatted, |
311 |
+ Handle<JSArray> result, int start_index, |
312 |
+ Handle<Object> numeric_obj, bool style_is_unit) { |
313 |
++ UErrorCode status = U_ZERO_ERROR; |
314 |
++ icu::UnicodeString formatted_text = formatted->toString(status); |
315 |
++ if (U_FAILURE(status)) { |
316 |
++ THROW_NEW_ERROR_RETURN_VALUE( |
317 |
++ isolate, NewTypeError(MessageTemplate::kIcuError), Nothing<int>()); |
318 |
++ } |
319 |
+ DCHECK(numeric_obj->IsNumeric()); |
320 |
+- int32_t length = formatted.length(); |
321 |
++ int32_t length = formatted_text.length(); |
322 |
+ int index = start_index; |
323 |
+ if (length == 0) return Just(index); |
324 |
+ |
325 |
+@@ -1419,13 +1420,14 @@ |
326 |
+ // other region covers some part of the formatted string. It's possible |
327 |
+ // there's another field with exactly the same begin and end as this backdrop, |
328 |
+ // in which case the backdrop's field_id of -1 will give it lower priority. |
329 |
+- regions.push_back(NumberFormatSpan(-1, 0, formatted.length())); |
330 |
++ regions.push_back(NumberFormatSpan(-1, 0, formatted_text.length())); |
331 |
+ |
332 |
+ { |
333 |
+- icu::FieldPosition fp; |
334 |
+- while (fp_iter->next(fp)) { |
335 |
+- regions.push_back(NumberFormatSpan(fp.getField(), fp.getBeginIndex(), |
336 |
+- fp.getEndIndex())); |
337 |
++ icu::ConstrainedFieldPosition cfp; |
338 |
++ cfp.constrainCategory(UFIELD_CATEGORY_NUMBER); |
339 |
++ while (formatted->nextPosition(cfp, status)) { |
340 |
++ regions.push_back( |
341 |
++ NumberFormatSpan(cfp.getField(), cfp.getStart(), cfp.getLimit())); |
342 |
+ } |
343 |
+ } |
344 |
+ |
345 |
+@@ -1447,7 +1449,7 @@ |
346 |
+ Handle<String> substring; |
347 |
+ ASSIGN_RETURN_ON_EXCEPTION_VALUE( |
348 |
+ isolate, substring, |
349 |
+- Intl::ToString(isolate, formatted, part.begin_pos, part.end_pos), |
350 |
++ Intl::ToString(isolate, formatted_text, part.begin_pos, part.end_pos), |
351 |
+ Nothing<int>()); |
352 |
+ Intl::AddElement(isolate, result, index, field_type_string, substring); |
353 |
+ ++index; |
354 |
+@@ -1467,20 +1469,19 @@ |
355 |
+ number_format->icu_number_formatter().raw(); |
356 |
+ CHECK_NOT_NULL(fmt); |
357 |
+ |
358 |
+- icu::FieldPositionIterator fp_iter; |
359 |
+- Maybe<icu::UnicodeString> maybe_format = |
360 |
+- IcuFormatNumber(isolate, *fmt, numeric_obj, &fp_iter); |
361 |
++ icu::number::FormattedNumber formatted; |
362 |
++ Maybe<bool> maybe_format = |
363 |
++ IcuFormatNumber(isolate, *fmt, numeric_obj, &formatted); |
364 |
+ MAYBE_RETURN(maybe_format, Handle<JSArray>()); |
365 |
+- |
366 |
+ UErrorCode status = U_ZERO_ERROR; |
367 |
++ |
368 |
+ bool style_is_unit = |
369 |
+ Style::UNIT == StyleFromSkeleton(fmt->toSkeleton(status)); |
370 |
+ CHECK(U_SUCCESS(status)); |
371 |
+ |
372 |
+ Handle<JSArray> result = factory->NewJSArray(0); |
373 |
+- Maybe<int> maybe_format_to_parts = |
374 |
+- ConstructParts(isolate, maybe_format.FromJust(), &fp_iter, result, 0, |
375 |
+- numeric_obj, style_is_unit); |
376 |
++ Maybe<int> maybe_format_to_parts = ConstructParts( |
377 |
++ isolate, &formatted, result, 0, numeric_obj, style_is_unit); |
378 |
+ MAYBE_RETURN(maybe_format_to_parts, Handle<JSArray>()); |
379 |
+ |
380 |
+ return result; |