diff options
Diffstat (limited to 'chromium')
70 files changed, 569 insertions, 2030 deletions
diff --git a/chromium/DEPS b/chromium/DEPS index 6bb2d382500..449cd8e92e9 100644 --- a/chromium/DEPS +++ b/chromium/DEPS @@ -477,7 +477,7 @@ deps = { (Var("webrtc_git")) + '/deps/third_party/openmax.git@b611996df3b8f6b151339d22c12c21f167009cb6', 'src/third_party/pdfium': { 'url': - '{pdfium_git}/pdfium.git@e839a6adb305467759e0d22fe7532a72fe4d8fa7' + '{pdfium_git}/pdfium.git@aaf58321fcaefae4bdf2419b5094f810cdcb1a49' }, 'src/third_party/pefile': { 'condition': @@ -523,7 +523,7 @@ deps = { (Var("chromium_git")) + '/external/github.com/google/shaderc.git@cd8793c34907073025af2622c28bcee64e9879a4', 'src/third_party/skia': { 'url': - '{skia_git}/skia.git@bd0dafbc8112f6cfa92a8096d8cb5696d8535ef9' + '{skia_git}/skia.git@3eace5f5bc494d185caa3787bce425e2098bd575' }, 'src/third_party/smhasher/src': (Var("chromium_git")) + '/external/smhasher.git@e87738e57558e0ec472b2fc3a643b838e5b6e88f', @@ -565,7 +565,7 @@ deps = { (Var("chromium_git")) + '/external/khronosgroup/webgl.git@d458ada06171a85af00367251a4ed55db7fe2018', 'src/third_party/webrtc': { 'url': - '{webrtc_git}/src.git@9f7e2a90da243288657e1802af85168e87daab01' + '{webrtc_git}/src.git@bccbc278e6b809b0b39f4b46e6f5a072f4123182' }, 'src/third_party/xdg-utils': { 'condition': @@ -583,7 +583,7 @@ deps = { (Var("chromium_git")) + '/infra/luci/client-py.git@88229872dd17e71658fe96763feaa77915d8cbd6', 'src/v8': { 'url': - '{chromium_git}/v8/v8.git@2bc5f566416da419601d55ffc83f92374be50779' + '{chromium_git}/v8/v8.git@8db46042ed29e8696d1ad58155e6efb182adebd7' } } @@ -1278,6 +1278,18 @@ hooks = [ }, { 'action': [ + 'python', + 'src/build/cipd/clobber_cipd_root.py', + '--root', + '.' + ], + 'pattern': + '.', + 'name': + 'Clobber Upcoming GClient CIPD Root' + }, + { + 'action': [ 'src/build/cipd/cipd_wrapper.py', '--chromium-root', 'src', diff --git a/chromium/build/cipd/clobber_cipd_root.py b/chromium/build/cipd/clobber_cipd_root.py new file mode 100755 index 00000000000..5d36c72239f --- /dev/null +++ b/chromium/build/cipd/clobber_cipd_root.py @@ -0,0 +1,33 @@ +#!/usr/bin/env python +# +# Copyright 2018 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +"""Clobbers a CIPD root.""" + +import argparse +import os +import shutil +import sys + + +def main(): + parser = argparse.ArgumentParser( + description='Clobbers the CIPD root in the given directory.') + + parser.add_argument( + '--root', + required=True, + help='Root directory for dependency.') + args = parser.parse_args() + + cipd_root_dir = os.path.join(args.root, '.cipd') + if os.path.exists(cipd_root_dir): + shutil.rmtree(cipd_root_dir) + + return 0 + + +if __name__ == '__main__': + sys.exit(main()) diff --git a/chromium/build/util/LASTCHANGE b/chromium/build/util/LASTCHANGE index 58b54769aeb..04eb90ff080 100644 --- a/chromium/build/util/LASTCHANGE +++ b/chromium/build/util/LASTCHANGE @@ -1 +1 @@ -LASTCHANGE=2b81d816997306dfdd0c2168d67028502f1cdee2- +LASTCHANGE=926d27280b919a1aeb0091392d56f63a38d2bc0b- diff --git a/chromium/chrome/VERSION b/chromium/chrome/VERSION index b118fa66a94..94fa64417f3 100644 --- a/chromium/chrome/VERSION +++ b/chromium/chrome/VERSION @@ -1,4 +1,4 @@ MAJOR=65 MINOR=0 BUILD=3325 -PATCH=151 +PATCH=230 diff --git a/chromium/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc b/chromium/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc index b334f627c8c..3860fef06c7 100644 --- a/chromium/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc +++ b/chromium/chrome/browser/devtools/global_confirm_info_bar_browsertest.cc @@ -15,6 +15,7 @@ #include "chrome/browser/ui/tabs/tab_strip_model.h" #include "chrome/test/base/in_process_browser_test.h" #include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobars_switches.h" #include "content/public/test/test_utils.h" namespace { @@ -54,6 +55,22 @@ class GlobalConfirmInfoBarTest : public InProcessBrowserTest { DISALLOW_COPY_AND_ASSIGN(GlobalConfirmInfoBarTest); }; +// Subclass for tests that require infobars to be disabled. +class GlobalConfirmInfoBarWithInfoBarDisabledTest + : public GlobalConfirmInfoBarTest { + public: + GlobalConfirmInfoBarWithInfoBarDisabledTest() = default; + ~GlobalConfirmInfoBarWithInfoBarDisabledTest() override = default; + + protected: + void SetUpCommandLine(base::CommandLine* command_line) override { + command_line->AppendSwitch(infobars::switches::kDisableInfoBars); + } + + private: + DISALLOW_COPY_AND_ASSIGN(GlobalConfirmInfoBarWithInfoBarDisabledTest); +}; + } // namespace // Creates a global confirm info bar on a browser with 2 tabs and closes it. @@ -129,3 +146,17 @@ IN_PROC_BROWSER_TEST_F(GlobalConfirmInfoBarTest, UserInteraction) { for (int i = 0; i < tab_strip_model->count(); i++) EXPECT_EQ(0u, GetInfoBarServiceFromTabIndex(i)->infobar_count()); } + +IN_PROC_BROWSER_TEST_F(GlobalConfirmInfoBarWithInfoBarDisabledTest, + InfoBarsDisabled) { + ASSERT_EQ(1, browser()->tab_strip_model()->count()); + + auto delegate = std::make_unique<TestConfirmInfoBarDelegate>(); + base::WeakPtr<GlobalConfirmInfoBar> global_confirm_info_bar = + GlobalConfirmInfoBar::Show(std::move(delegate)); + + // In this case, the deletion is done asynchronously. + content::RunAllPendingInMessageLoop(); + + ASSERT_FALSE(global_confirm_info_bar); +} diff --git a/chromium/chrome/browser/printing/print_view_manager_base.cc b/chromium/chrome/browser/printing/print_view_manager_base.cc index 59761b2d817..9c3ba082e01 100644 --- a/chromium/chrome/browser/printing/print_view_manager_base.cc +++ b/chromium/chrome/browser/printing/print_view_manager_base.cc @@ -190,6 +190,11 @@ void PrintViewManagerBase::PrintDocument( print_job_->StartPdfToEmfConversion(print_data, page_size, content_area, print_text_with_gdi); } + // Indicate that the PDF is fully rendered and we no longer need the renderer + // and web contents, so the print job does not need to be cancelled if they + // die. This is needed on Windows because the PrintedDocument will not be + // considered complete until PDF conversion finishes. + document->SetConvertingPdf(); #else std::unique_ptr<PdfMetafileSkia> metafile = std::make_unique<PdfMetafileSkia>(SkiaDocumentType::PDF); @@ -260,11 +265,9 @@ void PrintViewManagerBase::StartLocalPrintJob( gfx::Size page_size = settings.page_setup_device_units().physical_size(); gfx::Rect content_area = gfx::Rect(0, 0, page_size.width(), page_size.height()); - gfx::Point offsets = - gfx::Point(settings.page_setup_device_units().content_area().x(), - settings.page_setup_device_units().content_area().y()); - PrintDocument(document, print_data, page_size, content_area, offsets); + PrintDocument(document, print_data, page_size, content_area, + settings.page_setup_device_units().printable_area().origin()); std::move(callback).Run(base::Value()); } #endif // BUILDFLAG(ENABLE_PRINT_PREVIEW) @@ -506,6 +509,12 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() { if (!print_job_.get() || !print_job_->is_job_pending()) return false; + // Is the document already complete? + if (print_job_->document() && print_job_->document()->IsComplete()) { + printing_succeeded_ = true; + return true; + } + // We can't print if there is no renderer. if (!web_contents() || !web_contents()->GetRenderViewHost() || @@ -513,12 +522,6 @@ bool PrintViewManagerBase::RenderAllMissingPagesNow() { return false; } - // Is the document already complete? - if (print_job_->document() && print_job_->document()->IsComplete()) { - printing_succeeded_ = true; - return true; - } - // WebContents is either dying or a second consecutive request to print // happened before the first had time to finish. We need to render all the // pages in an hurry if a print_job_ is still pending. No need to wait for it diff --git a/chromium/chrome/browser/resources/pdf/manifest.json b/chromium/chrome/browser/resources/pdf/manifest.json index 3b45a058c94..c3d0a802dd8 100644 --- a/chromium/chrome/browser/resources/pdf/manifest.json +++ b/chromium/chrome/browser/resources/pdf/manifest.json @@ -8,7 +8,7 @@ "offline_enabled": true, "incognito": "split", "permissions": [ - "<all_urls>", + "chrome://resources/", "metricsPrivate", "resourcesPrivate" ], diff --git a/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc b/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc index 7d992e1fae3..906dbf0f698 100644 --- a/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc +++ b/chromium/chrome/browser/ui/webui/settings/md_settings_localized_strings_provider.cc @@ -231,9 +231,8 @@ void AddA11yStrings(content::WebUIDataSource* html_source) { arraysize(localized_strings)); #if defined(OS_CHROMEOS) - html_source->AddString( - "a11yLearnMoreUrl", - GetHelpUrlWithBoard(chrome::kChromeAccessibilityHelpURL)); + html_source->AddString("a11yLearnMoreUrl", + chrome::kChromeAccessibilityHelpURL); html_source->AddBoolean( "showExperimentalA11yFeatures", diff --git a/chromium/components/exo/pointer.cc b/chromium/components/exo/pointer.cc index 62ccbe27047..6e46f09336d 100644 --- a/chromium/components/exo/pointer.cc +++ b/chromium/components/exo/pointer.cc @@ -95,7 +95,6 @@ Pointer::~Pointer() { delegate_->OnPointerDestroying(this); if (focus_surface_) { focus_surface_->RemoveSurfaceObserver(this); - focus_surface_->UnregisterCursorProvider(this); } if (pinch_delegate_) pinch_delegate_->OnPointerDestroying(this); @@ -151,10 +150,6 @@ void Pointer::SetGesturePinchDelegate(PointerGesturePinchDelegate* delegate) { pinch_delegate_ = delegate; } -gfx::NativeCursor Pointer::GetCursor() { - return cursor_; -} - //////////////////////////////////////////////////////////////////////////////// // SurfaceDelegate overrides: @@ -358,7 +353,6 @@ void Pointer::SetFocus(Surface* surface, focus_surface_->RemoveSurfaceObserver(this); // Require SetCursor() to be called and cursor to be re-defined in // response to each OnPointerEnter() call. - focus_surface_->UnregisterCursorProvider(this); focus_surface_ = nullptr; cursor_capture_weak_ptr_factory_.InvalidateWeakPtrs(); } @@ -368,7 +362,6 @@ void Pointer::SetFocus(Surface* surface, location_ = location; focus_surface_ = surface; focus_surface_->AddSurfaceObserver(this); - focus_surface_->RegisterCursorProvider(this); } delegate_->OnPointerFrame(); } diff --git a/chromium/components/exo/pointer.h b/chromium/components/exo/pointer.h index 5a87744b876..56a0753a74b 100644 --- a/chromium/components/exo/pointer.h +++ b/chromium/components/exo/pointer.h @@ -58,9 +58,6 @@ class Pointer : public SurfaceTreeHost, // Set delegate for pinch events. void SetGesturePinchDelegate(PointerGesturePinchDelegate* delegate); - // Returns the current cursor for the pointer. - gfx::NativeCursor GetCursor(); - // Overridden from SurfaceDelegate: void OnSurfaceCommit() override; diff --git a/chromium/components/exo/surface.cc b/chromium/components/exo/surface.cc index be321c416bf..4ec4511ac0c 100644 --- a/chromium/components/exo/surface.cc +++ b/chromium/components/exo/surface.cc @@ -116,7 +116,11 @@ class CustomWindowDelegate : public aura::WindowDelegate { void OnBoundsChanged(const gfx::Rect& old_bounds, const gfx::Rect& new_bounds) override {} gfx::NativeCursor GetCursor(const gfx::Point& point) override { - return surface_->GetCursor(); + views::Widget* widget = + views::Widget::GetTopLevelWidgetForNativeView(surface_->window()); + if (widget) + return widget->GetNativeWindow()->GetCursor(point /* not used */); + return ui::CursorType::kNull; } int GetNonClientComponent(const gfx::Point& point) const override { return HTNOWHERE; @@ -653,25 +657,6 @@ Surface::GetHitTestShapeRects() const { return rects; } -void Surface::RegisterCursorProvider(Pointer* provider) { - cursor_providers_.insert(provider); -} - -void Surface::UnregisterCursorProvider(Pointer* provider) { - cursor_providers_.erase(provider); -} - -gfx::NativeCursor Surface::GetCursor() { - // What cursor we display when we have multiple cursor providers is not - // important. Return the first non-null cursor. - for (auto* cursor_provider : cursor_providers_) { - gfx::NativeCursor cursor = cursor_provider->GetCursor(); - if (cursor != ui::CursorType::kNull) - return cursor; - } - return ui::CursorType::kNull; -} - void Surface::SetSurfaceDelegate(SurfaceDelegate* delegate) { DCHECK(!delegate_ || !delegate); delegate_ = delegate; diff --git a/chromium/components/exo/surface.h b/chromium/components/exo/surface.h index efac96f8a68..54215f634ee 100644 --- a/chromium/components/exo/surface.h +++ b/chromium/components/exo/surface.h @@ -43,7 +43,6 @@ class CompositorFrame; namespace exo { class Buffer; class LayerTreeFrameSinkHolder; -class Pointer; class SurfaceObserver; class Surface; @@ -54,10 +53,6 @@ class PropertyHelper; // Counter-clockwise rotations. enum class Transform { NORMAL, ROTATE_90, ROTATE_180, ROTATE_270 }; -// The pointer class is currently the only cursor provider class but this can -// change in the future when better hardware cursor support is added. -using CursorProvider = Pointer; - // This class represents a rectangular area that is displayed on the screen. // It has a location, size and pixel contents. class Surface final : public ui::PropertyHandler { @@ -198,15 +193,6 @@ class Surface final : public ui::PropertyHandler { std::unique_ptr<aura::WindowTargeter::HitTestRects> GetHitTestShapeRects() const; - // Surface does not own cursor providers. It is the responsibility of the - // caller to remove the cursor provider before it is destroyed. - void RegisterCursorProvider(CursorProvider* provider); - void UnregisterCursorProvider(CursorProvider* provider); - - // Returns the cursor for the surface. If no cursor provider is registered - // then CursorType::kNull is returned. - gfx::NativeCursor GetCursor(); - // Set the surface delegate. void SetSurfaceDelegate(SurfaceDelegate* delegate); @@ -397,9 +383,6 @@ class Surface final : public ui::PropertyHandler { // callbacks when compositing successfully ends. base::TimeTicks last_compositing_start_time_; - // Cursor providers. Surface does not own the cursor providers. - std::set<CursorProvider*> cursor_providers_; - // This can be set to have some functions delegated. E.g. ShellSurface class // can set this to handle Commit() and apply any double buffered state it // maintains. diff --git a/chromium/components/infobars/core/BUILD.gn b/chromium/components/infobars/core/BUILD.gn index acb93749993..103e359078f 100644 --- a/chromium/components/infobars/core/BUILD.gn +++ b/chromium/components/infobars/core/BUILD.gn @@ -21,6 +21,8 @@ static_library("core") { "infobar_delegate.h", "infobar_manager.cc", "infobar_manager.h", + "infobars_switches.cc", + "infobars_switches.h", "simple_alert_infobar_delegate.cc", "simple_alert_infobar_delegate.h", ] diff --git a/chromium/components/infobars/core/infobar_manager.cc b/chromium/components/infobars/core/infobar_manager.cc index 70058559499..7f6a4c9f007 100644 --- a/chromium/components/infobars/core/infobar_manager.cc +++ b/chromium/components/infobars/core/infobar_manager.cc @@ -8,6 +8,7 @@ #include "base/command_line.h" #include "components/infobars/core/infobar.h" +#include "components/infobars/core/infobars_switches.h" namespace infobars { @@ -37,6 +38,9 @@ void InfoBarManager::Observer::OnManagerShuttingDown(InfoBarManager* manager) { InfoBar* InfoBarManager::AddInfoBar(std::unique_ptr<InfoBar> infobar, bool replace_existing) { DCHECK(infobar); + if (!infobars_enabled_) + return nullptr; + for (InfoBars::const_iterator i(infobars_.begin()); i != infobars_.end(); ++i) { if ((*i)->delegate()->EqualsDelegate(infobar->delegate())) { @@ -67,6 +71,8 @@ void InfoBarManager::RemoveAllInfoBars(bool animate) { InfoBar* InfoBarManager::ReplaceInfoBar(InfoBar* old_infobar, std::unique_ptr<InfoBar> new_infobar) { DCHECK(old_infobar); + if (!infobars_enabled_) + return AddInfoBar(std::move(new_infobar)); // Deletes the infobar. DCHECK(new_infobar); InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), @@ -97,6 +103,9 @@ void InfoBarManager::RemoveObserver(Observer* obs) { } InfoBarManager::InfoBarManager() { + if (base::CommandLine::ForCurrentProcess()->HasSwitch( + switches::kDisableInfoBars)) + infobars_enabled_ = false; } InfoBarManager::~InfoBarManager() {} @@ -133,6 +142,11 @@ void InfoBarManager::NotifyInfoBarRemoved(InfoBar* infobar, bool animate) { void InfoBarManager::RemoveInfoBarInternal(InfoBar* infobar, bool animate) { DCHECK(infobar); + if (!infobars_enabled_) { + DCHECK(infobars_.empty()); + return; + } + InfoBars::iterator i(std::find(infobars_.begin(), infobars_.end(), infobar)); DCHECK(i != infobars_.end()); diff --git a/chromium/components/infobars/core/infobar_manager.h b/chromium/components/infobars/core/infobar_manager.h index 9ae6c065ba2..2d44965cbe6 100644 --- a/chromium/components/infobars/core/infobar_manager.h +++ b/chromium/components/infobars/core/infobar_manager.h @@ -132,6 +132,7 @@ class InfoBarManager { void RemoveInfoBarInternal(InfoBar* infobar, bool animate); InfoBars infobars_; + bool infobars_enabled_ = true; bool animations_enabled_ = true; base::ObserverList<Observer, true> observer_list_; diff --git a/chromium/components/infobars/core/infobars_switches.cc b/chromium/components/infobars/core/infobars_switches.cc new file mode 100644 index 00000000000..deb21a76a1a --- /dev/null +++ b/chromium/components/infobars/core/infobars_switches.cc @@ -0,0 +1,14 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "components/infobars/core/infobars_switches.h" + +namespace infobars { +namespace switches { + +// Prevent infobars from appearing. +const char kDisableInfoBars[] = "disable-infobars"; + +} // namespace switches +} // namespace infobars diff --git a/chromium/components/infobars/core/infobars_switches.h b/chromium/components/infobars/core/infobars_switches.h new file mode 100644 index 00000000000..d24a09a417f --- /dev/null +++ b/chromium/components/infobars/core/infobars_switches.h @@ -0,0 +1,16 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ +#define COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ + +namespace infobars { +namespace switches { + +extern const char kDisableInfoBars[]; + +} // namespace switches +} // namespace infobars + +#endif // COMPONENTS_INFOBARS_CORE_INFOBARS_SWITCHES_H_ diff --git a/chromium/gpu/command_buffer/service/sync_point_manager.cc b/chromium/gpu/command_buffer/service/sync_point_manager.cc index a3c4bf152e0..7fdf99e7e13 100644 --- a/chromium/gpu/command_buffer/service/sync_point_manager.cc +++ b/chromium/gpu/command_buffer/service/sync_point_manager.cc @@ -72,8 +72,9 @@ void SyncPointOrderData::Destroy() { uint32_t SyncPointOrderData::GenerateUnprocessedOrderNumber() { base::AutoLock auto_lock(lock_); DCHECK(!destroyed_); - unprocessed_order_num_ = sync_point_manager_->GenerateOrderNumber(); - return unprocessed_order_num_; + last_unprocessed_order_num_ = sync_point_manager_->GenerateOrderNumber(); + unprocessed_order_nums_.push(last_unprocessed_order_num_); + return last_unprocessed_order_num_; } void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { @@ -85,29 +86,6 @@ void SyncPointOrderData::BeginProcessingOrderNumber(uint32_t order_num) { DCHECK_LE(order_num, unprocessed_order_num()); current_order_num_ = order_num; paused_ = false; - - // Catch invalid waits which were waiting on fence syncs that do not exist. - // When we begin processing an order number, we should release any fence - // syncs which were enqueued but the order number never existed. - // Release without the lock to avoid possible deadlocks. - std::vector<OrderFence> ensure_releases; - { - base::AutoLock auto_lock(lock_); - while (!order_fence_queue_.empty()) { - const OrderFence& order_fence = order_fence_queue_.top(); - if (order_fence_queue_.top().order_num < order_num) { - ensure_releases.push_back(order_fence); - order_fence_queue_.pop(); - continue; - } - break; - } - } - - for (OrderFence& order_fence : ensure_releases) { - order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, - order_fence.release_callback); - } } void SyncPointOrderData::PauseProcessingOrderNumber(uint32_t order_num) { @@ -132,9 +110,20 @@ void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) { DCHECK_GT(order_num, processed_order_num_); processed_order_num_ = order_num; + DCHECK(!unprocessed_order_nums_.empty()); + DCHECK_EQ(order_num, unprocessed_order_nums_.front()); + unprocessed_order_nums_.pop(); + + uint32_t next_order_num = 0; + if (!unprocessed_order_nums_.empty()) + next_order_num = unprocessed_order_nums_.front(); + while (!order_fence_queue_.empty()) { const OrderFence& order_fence = order_fence_queue_.top(); - if (order_fence_queue_.top().order_num <= order_num) { + // It's possible for the fence's order number to equal next order number. + // This happens when the wait was enqueued with an order number greater + // than the last unprocessed order number. So don't release the fence yet. + if (!next_order_num || order_fence.order_num < next_order_num) { ensure_releases.push_back(order_fence); order_fence_queue_.pop(); continue; @@ -144,6 +133,7 @@ void SyncPointOrderData::FinishProcessingOrderNumber(uint32_t order_num) { } for (OrderFence& order_fence : ensure_releases) { + DLOG(ERROR) << "Client did not release sync token as expected"; order_fence.client_state->EnsureWaitReleased(order_fence.fence_release, order_fence.release_callback); } @@ -158,19 +148,22 @@ bool SyncPointOrderData::ValidateReleaseOrderNumber( if (destroyed_) return false; - // Release should have a possible unprocessed order number lower than the wait - // order number. - if ((processed_order_num_ + 1) >= wait_order_num) + // We should have unprocessed order numbers which could potentially release + // this fence. + if (unprocessed_order_nums_.empty()) return false; - // Release should have more unprocessed numbers if we are waiting. - if (unprocessed_order_num_ <= processed_order_num_) + // We should have an unprocessed order number lower than the wait order + // number for the wait to be valid. It's not possible for wait order number to + // equal next unprocessed order number, but we handle that defensively. + DCHECK_NE(wait_order_num, unprocessed_order_nums_.front()); + if (wait_order_num <= unprocessed_order_nums_.front()) return false; // So far it could be valid, but add an order fence guard to be sure it // gets released eventually. uint32_t expected_order_num = - std::min(unprocessed_order_num_, wait_order_num); + std::min(unprocessed_order_nums_.back(), wait_order_num); order_fence_queue_.push(OrderFence(expected_order_num, fence_release, release_callback, std::move(client_state))); @@ -237,17 +230,20 @@ bool SyncPointClientState::WaitForRelease(uint64_t release, const base::Closure& callback) { // Lock must be held the whole time while we validate otherwise it could be // released while we are checking. - { - base::AutoLock auto_lock(fence_sync_lock_); - if (release > fence_sync_release_ && - order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, - callback)) { - // Add the callback which will be called upon release. - release_callback_queue_.push(ReleaseCallback(release, callback)); - return true; - } - } + base::AutoLock auto_lock(fence_sync_lock_); + // Already released, do not run the callback. + if (release <= fence_sync_release_) + return false; + + if (order_data_->ValidateReleaseOrderNumber(this, wait_order_num, release, + callback)) { + // Add the callback which will be called upon release. + release_callback_queue_.push(ReleaseCallback(release, callback)); + return true; + } + + DLOG(ERROR) << "Client waiting on non-existent sync token"; return false; } diff --git a/chromium/gpu/command_buffer/service/sync_point_manager.h b/chromium/gpu/command_buffer/service/sync_point_manager.h index be8e510d30f..ca5c4c95583 100644 --- a/chromium/gpu/command_buffer/service/sync_point_manager.h +++ b/chromium/gpu/command_buffer/service/sync_point_manager.h @@ -51,7 +51,7 @@ class GPU_EXPORT SyncPointOrderData uint32_t unprocessed_order_num() const { base::AutoLock auto_lock(lock_); - return unprocessed_order_num_; + return last_unprocessed_order_num_; } uint32_t current_order_num() const { @@ -122,9 +122,7 @@ class GPU_EXPORT SyncPointOrderData bool paused_ = false; // This lock protects destroyed_, processed_order_num_, - // unprocessed_order_num_, and order_fence_queue_. All order numbers (n) in - // order_fence_queue_ must follow the invariant: - // processed_order_num_ < n <= unprocessed_order_num_. + // unprocessed_order_nums_, and order_fence_queue_. mutable base::Lock lock_; bool destroyed_ = false; @@ -132,8 +130,13 @@ class GPU_EXPORT SyncPointOrderData // Last finished IPC order number. uint32_t processed_order_num_ = 0; - // Unprocessed order number expected to be processed under normal execution. - uint32_t unprocessed_order_num_ = 0; + // Last unprocessed order number. Updated in GenerateUnprocessedOrderNumber. + uint32_t last_unprocessed_order_num_ = 0; + + // Queue of unprocessed order numbers. Order numbers are enqueued in + // GenerateUnprocessedOrderNumber, and dequeued in + // FinishProcessingOrderNumber. + std::queue<uint32_t> unprocessed_order_nums_; // In situations where we are waiting on fence syncs that do not exist, we // validate by making sure the order number does not pass the order number @@ -141,7 +144,9 @@ class GPU_EXPORT SyncPointOrderData // wait command's, we should automatically release up to the expected // release count. Note that this also releases other lower release counts, // so a single misbehaved fence sync is enough to invalidate/signal all - // previous fence syncs. + // previous fence syncs. All order numbers (n) in order_fence_queue_ must + // follow the invariant: + // unprocessed_order_nums_.front() < n <= unprocessed_order_nums_.back(). OrderFenceQueue order_fence_queue_; DISALLOW_COPY_AND_ASSIGN(SyncPointOrderData); diff --git a/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc b/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc index a72c48a504b..f926a747baf 100644 --- a/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc +++ b/chromium/gpu/command_buffer/service/sync_point_manager_unittest.cc @@ -431,26 +431,20 @@ TEST_F(SyncPointManagerTest, NonExistentOrderNumRelease) { EXPECT_TRUE(valid_wait); EXPECT_EQ(10, test_num); - // Release stream should know it should release fence sync by order [3], - // so going through order [1] should not release it yet. + // Release stream should know it should release fence sync by order [3], but + // it has no unprocessed order numbers less than 3, so it runs the callback. release_stream.BeginProcessing(); EXPECT_EQ(1u, release_stream.order_data->current_order_num()); release_stream.EndProcessing(); EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); - EXPECT_EQ(10, test_num); - - // Beginning order [4] should immediately trigger the wait although the fence - // sync is still not released yet. - release_stream.BeginProcessing(); - EXPECT_EQ(4u, release_stream.order_data->current_order_num()); EXPECT_EQ(123, test_num); - EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); // Ensure that the wait callback does not get triggered again when it is // actually released. - test_num = 1; + release_stream.BeginProcessing(); + test_num = 10; release_stream.client_state->ReleaseFenceSync(1); - EXPECT_EQ(1, test_num); + EXPECT_EQ(10, test_num); EXPECT_TRUE(sync_point_manager_->IsSyncTokenReleased(sync_token)); } @@ -480,4 +474,123 @@ TEST_F(SyncPointManagerTest, WaitOnSameSequenceFails) { EXPECT_FALSE(sync_point_manager_->IsSyncTokenReleased(sync_token)); } +TEST_F(SyncPointManagerTest, HandleInvalidWaitOrderNumber) { + CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; + CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); + CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); + + SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId1); + SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId2); + + stream1.AllocateOrderNum(); // stream 1, order num 1 + stream2.AllocateOrderNum(); // stream 2, order num 2 + stream2.AllocateOrderNum(); // stream 2, order num 3 + stream1.AllocateOrderNum(); // stream 1, order num 4 + + // Run stream 1, order num 1. + stream1.BeginProcessing(); + stream1.EndProcessing(); + + // Stream 2 waits on stream 1 with order num 3. This wait is invalid because + // there's no unprocessed order num less than 3 on stream 1. + int test_num = 10; + bool valid_wait = sync_point_manager_->Wait( + SyncToken(kNamespaceId, kCmdBufferId1, 1), + stream2.order_data->sequence_id(), 3, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_FALSE(valid_wait); + EXPECT_EQ(10, test_num); +} + +TEST_F(SyncPointManagerTest, RetireInvalidWaitAfterOrderNumberPasses) { + CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; + CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); + CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); + + SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId1); + SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId2); + + stream1.AllocateOrderNum(); // stream 1, order num 1 + stream1.AllocateOrderNum(); // stream 1, order num 2 + stream2.AllocateOrderNum(); // stream 2, order num 3 + + // Stream 2 waits on stream 1 with order num 3. + int test_num = 10; + bool valid_wait = sync_point_manager_->Wait( + SyncToken(kNamespaceId, kCmdBufferId1, 1), + stream2.order_data->sequence_id(), 3, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num); + + stream1.AllocateOrderNum(); // stream 1, order num 4 + + // Run stream 1, order num 1. The wait isn't retired. + stream1.BeginProcessing(); + stream1.EndProcessing(); + EXPECT_EQ(10, test_num); + + // Run stream 1, order num 2. Wait is retired because we reach the last order + // number that was unprocessed at the time the wait was enqueued. + stream1.BeginProcessing(); + stream1.EndProcessing(); + EXPECT_EQ(123, test_num); +} + +TEST_F(SyncPointManagerTest, HandleInvalidCyclicWaits) { + CommandBufferNamespace kNamespaceId = gpu::CommandBufferNamespace::GPU_IO; + CommandBufferId kCmdBufferId1 = CommandBufferId::FromUnsafeValue(0x123); + CommandBufferId kCmdBufferId2 = CommandBufferId::FromUnsafeValue(0x234); + + SyncPointStream stream1(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId1); + SyncPointStream stream2(sync_point_manager_.get(), kNamespaceId, + kCmdBufferId2); + + stream1.AllocateOrderNum(); // stream 1, order num 1 + stream2.AllocateOrderNum(); // stream 2, order num 2 + stream1.AllocateOrderNum(); // stream 1, order num 3 + stream2.AllocateOrderNum(); // stream 2, order num 4 + + // Stream 2 waits on stream 1 with order num 2. + int test_num1 = 10; + bool valid_wait = sync_point_manager_->Wait( + SyncToken(kNamespaceId, kCmdBufferId1, 1), + stream2.order_data->sequence_id(), 2, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num1, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num1); + + // Stream 1 waits on stream 2 with order num 3. + int test_num2 = 10; + valid_wait = sync_point_manager_->Wait( + SyncToken(kNamespaceId, kCmdBufferId2, 1), + stream1.order_data->sequence_id(), 3, + base::Bind(&SyncPointManagerTest::SetIntegerFunction, &test_num2, 123)); + EXPECT_TRUE(valid_wait); + EXPECT_EQ(10, test_num2); + + // Run stream 1, order num 1. + stream1.BeginProcessing(); + stream1.EndProcessing(); + + // Since there's no unprocessed order num less than 2 on stream 1, the wait is + // released. + EXPECT_EQ(123, test_num1); + EXPECT_EQ(10, test_num2); + + // Run stream 2, order num 2. + stream2.BeginProcessing(); + stream2.EndProcessing(); + + // Since there's no unprocessed order num less than 3 on stream 2, the wait is + // released. + EXPECT_EQ(123, test_num1); + EXPECT_EQ(123, test_num2); +} + } // namespace gpu diff --git a/chromium/gpu/config/gpu_lists_version.h b/chromium/gpu/config/gpu_lists_version.h index 3d89bf18a19..2cc6499bd40 100644 --- a/chromium/gpu/config/gpu_lists_version.h +++ b/chromium/gpu/config/gpu_lists_version.h @@ -3,6 +3,6 @@ #ifndef GPU_CONFIG_GPU_LISTS_VERSION_H_ #define GPU_CONFIG_GPU_LISTS_VERSION_H_ -#define GPU_LISTS_VERSION "2b81d816997306dfdd0c2168d67028502f1cdee2" +#define GPU_LISTS_VERSION "926d27280b919a1aeb0091392d56f63a38d2bc0b" #endif // GPU_CONFIG_GPU_LISTS_VERSION_H_ diff --git a/chromium/ppapi/proxy/ppapi_command_buffer_proxy.cc b/chromium/ppapi/proxy/ppapi_command_buffer_proxy.cc index c518f944a02..665a2d2bb3b 100644 --- a/chromium/ppapi/proxy/ppapi_command_buffer_proxy.cc +++ b/chromium/ppapi/proxy/ppapi_command_buffer_proxy.cc @@ -170,6 +170,11 @@ void PpapiCommandBufferProxy::SetLock(base::Lock*) { } void PpapiCommandBufferProxy::EnsureWorkVisible() { + if (last_state_.error != gpu::error::kNoError) + return; + + if (flush_info_->flush_pending) + FlushInternal(); DCHECK_GE(flushed_fence_sync_release_, validated_fence_sync_release_); Send(new PpapiHostMsg_PPBGraphics3D_EnsureWorkVisible( ppapi::API_ID_PPB_GRAPHICS_3D, resource_)); diff --git a/chromium/printing/printed_document.cc b/chromium/printing/printed_document.cc index 05987fcf959..bc5aeccb466 100644 --- a/chromium/printing/printed_document.cc +++ b/chromium/printing/printed_document.cc @@ -131,6 +131,11 @@ PrintedDocument::PrintedDocument(const PrintSettings& settings, PrintedDocument::~PrintedDocument() = default; #if defined(OS_WIN) +void PrintedDocument::SetConvertingPdf() { + base::AutoLock lock(lock_); + mutable_.converting_pdf_ = true; +} + void PrintedDocument::SetPage(int page_number, std::unique_ptr<MetafilePlayer> metafile, float shrink, @@ -195,6 +200,9 @@ bool PrintedDocument::IsComplete() const { if (!mutable_.page_count_) return false; #if defined(OS_WIN) + if (mutable_.converting_pdf_) + return true; + PageNumber page(immutable_.settings_, mutable_.page_count_); if (page == PageNumber::npos()) return false; diff --git a/chromium/printing/printed_document.h b/chromium/printing/printed_document.h index 9a52abb6d28..08d9946fa22 100644 --- a/chromium/printing/printed_document.h +++ b/chromium/printing/printed_document.h @@ -43,6 +43,11 @@ class PRINTING_EXPORT PrintedDocument int cookie); #if defined(OS_WIN) + // Indicates that the PDF has been generated and the document is waiting for + // conversion for printing. This is needed on Windows so that the print job + // is not cancelled if the web contents dies before PDF conversion finishes. + void SetConvertingPdf(); + // Sets a page's data. 0-based. Note: locks for a short amount of time. void SetPage(int page_number, std::unique_ptr<MetafilePlayer> metafile, @@ -78,7 +83,7 @@ class PRINTING_EXPORT PrintedDocument // Returns true if all the necessary pages for the settings are already // rendered. - // Note: locks while parsing the whole tree. + // Note: This function always locks and may parse the whole tree. bool IsComplete() const; // Sets the number of pages in the document to be rendered. Can only be set @@ -153,6 +158,9 @@ class PRINTING_EXPORT PrintedDocument // Contains the pages' representation. This is a collection of PrintedPage. // Warning: Lock must be held when accessing this member. PrintedPages pages_; + + // Whether the PDF is being converted for printing. + bool converting_pdf_ = false; #else std::unique_ptr<MetafilePlayer> metafile_; #endif diff --git a/chromium/skia/ext/skia_commit_hash.h b/chromium/skia/ext/skia_commit_hash.h index 7d2f8edb2a2..eb07078edde 100644 --- a/chromium/skia/ext/skia_commit_hash.h +++ b/chromium/skia/ext/skia_commit_hash.h @@ -3,6 +3,6 @@ #ifndef SKIA_EXT_SKIA_COMMIT_HASH_H_ #define SKIA_EXT_SKIA_COMMIT_HASH_H_ -#define SKIA_COMMIT_HASH "c26a7bc8b8069f0f77ba3e4fb042e18116456ede-" +#define SKIA_COMMIT_HASH "35ee3617fcb08e0d79e6b9e6c05db23cc9416d4f-" #endif // SKIA_EXT_SKIA_COMMIT_HASH_H_ diff --git a/chromium/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp b/chromium/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp index a4ccb3ed5a9..10e39e88361 100644 --- a/chromium/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp +++ b/chromium/third_party/WebKit/Source/core/paint/PaintLayerPainter.cpp @@ -678,7 +678,8 @@ bool PaintLayerPainter::NeedsToClip( // the embedded content itself. Doing so would clip out the // border because LayoutEmbeddedObject does not obey the painting phases // of a normal box object. - if (layout_object.IsLayoutEmbeddedContent()) + if (layout_object.IsLayoutEmbeddedContent() && + layout_object.GetCompositingState() == kPaintsIntoOwnBacking) return paint_flags & kPaintLayerPaintingChildClippingMaskPhase; return clip_rect.Rect() != local_painting_info.paint_dirty_rect || diff --git a/chromium/third_party/libusb/src/libusb/os/windows_usb.c b/chromium/third_party/libusb/src/libusb/os/windows_usb.c index bc4def6073e..48ea08ca105 100644 --- a/chromium/third_party/libusb/src/libusb/os/windows_usb.c +++ b/chromium/third_party/libusb/src/libusb/os/windows_usb.c @@ -65,20 +65,6 @@ static int winusbx_abort_transfers(int sub_api, struct usbi_transfer *itransfer) static int winusbx_abort_control(int sub_api, struct usbi_transfer *itransfer); static int winusbx_reset_device(int sub_api, struct libusb_device_handle *dev_handle); static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); -// HID API prototypes -static int hid_init(int sub_api, struct libusb_context *ctx); -static int hid_exit(int sub_api); -static int hid_open(int sub_api, struct libusb_device_handle *dev_handle); -static void hid_close(int sub_api, struct libusb_device_handle *dev_handle); -static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); -static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface); -static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting); -static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer); -static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer); -static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint); -static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer); -static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle); -static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size); // Composite API prototypes static int composite_init(int sub_api, struct libusb_context *ctx); static int composite_exit(int sub_api); @@ -117,8 +103,6 @@ HANDLE timer_response = NULL; if (!WinUSBX[sub_api].initialized) return LIBUSB_ERROR_ACCESS; } while(0) static struct winusb_interface WinUSBX[SUB_API_MAX]; const char* sub_api_name[SUB_API_MAX] = WINUSBX_DRV_NAMES; -bool api_hid_available = false; -#define CHECK_HID_AVAILABLE do { if (!api_hid_available) return LIBUSB_ERROR_ACCESS; } while (0) static inline BOOLEAN guid_eq(const GUID *guid1, const GUID *guid2) { if ((guid1 != NULL) && (guid2 != NULL)) { @@ -733,7 +717,6 @@ static int auto_claim(struct libusb_transfer *transfer, int *interface_number, i switch(api_type) { case USB_API_WINUSBX: - case USB_API_HID: break; default: return LIBUSB_ERROR_INVALID_PARAM; @@ -1277,13 +1260,6 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev } if (priv->usb_interface[interface_number].path != NULL) { - if (api == USB_API_HID) { - // HID devices can have multiple collections (COL##) for each MI_## interface - usbi_dbg("interface[%d] already set - ignoring HID collection: %s", - interface_number, device_id); - return LIBUSB_ERROR_ACCESS; - } - // In other cases, just use the latest data safe_free(priv->usb_interface[interface_number].path); } @@ -1291,40 +1267,7 @@ static int set_composite_interface(struct libusb_context* ctx, struct libusb_dev priv->usb_interface[interface_number].path = dev_interface_path; priv->usb_interface[interface_number].apib = &usb_api_backend[api]; priv->usb_interface[interface_number].sub_api = sub_api; - if ((api == USB_API_HID) && (priv->hid == NULL)) { - priv->hid = (struct hid_device_priv*) calloc(1, sizeof(struct hid_device_priv)); - if (priv->hid == NULL) - return LIBUSB_ERROR_NO_MEM; - } - - return LIBUSB_SUCCESS; -} - -static int set_hid_interface(struct libusb_context* ctx, struct libusb_device* dev, - char* dev_interface_path) -{ - int i; - struct windows_device_priv *priv = _device_priv(dev); - - if (priv->hid == NULL) { - usbi_err(ctx, "program assertion failed: parent is not HID"); - return LIBUSB_ERROR_NO_DEVICE; - } - if (priv->hid->nb_interfaces == USB_MAXINTERFACES) { - usbi_err(ctx, "program assertion failed: max USB interfaces reached for HID device"); - return LIBUSB_ERROR_NO_DEVICE; - } - for (i=0; i<priv->hid->nb_interfaces; i++) { - if (safe_strcmp(priv->usb_interface[i].path, dev_interface_path) == 0) { - usbi_dbg("interface[%d] already set to %s", i, dev_interface_path); - return LIBUSB_SUCCESS; - } - } - priv->usb_interface[priv->hid->nb_interfaces].path = dev_interface_path; - priv->usb_interface[priv->hid->nb_interfaces].apib = &usb_api_backend[USB_API_HID]; - usbi_dbg("interface[%d] = %s", priv->hid->nb_interfaces, dev_interface_path); - priv->hid->nb_interfaces++; return LIBUSB_SUCCESS; } @@ -1338,14 +1281,12 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered const char* usb_class[] = {"USB", "NUSB3", "IUSB3"}; SP_DEVINFO_DATA dev_info_data = { 0 }; SP_DEVICE_INTERFACE_DETAIL_DATA_A *dev_interface_details = NULL; - GUID hid_guid; #define MAX_ENUM_GUIDS 64 const GUID* guid[MAX_ENUM_GUIDS]; #define HCD_PASS 0 #define HUB_PASS 1 #define GEN_PASS 2 #define DEV_PASS 3 -#define HID_PASS 4 int r = LIBUSB_SUCCESS; int api, sub_api; size_t class_index = 0; @@ -1372,17 +1313,14 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered // PASS 3 : (re)enumerate generic USB devices (including driverless) // and list additional USB device interface GUIDs to explore // PASS 4 : (re)enumerate master USB devices that have a device interface - // PASS 5+: (re)enumerate device interfaced GUIDs (including HID) and - // set the device interfaces. + // PASS 5+: (re)enumerate device interfaced GUIDs and set the device interfaces. // Init the GUID table guid[HCD_PASS] = &GUID_DEVINTERFACE_USB_HOST_CONTROLLER; guid[HUB_PASS] = &GUID_DEVINTERFACE_USB_HUB; guid[GEN_PASS] = NULL; guid[DEV_PASS] = &GUID_DEVINTERFACE_USB_DEVICE; - HidD_GetHidGuid(&hid_guid); - guid[HID_PASS] = &hid_guid; - nb_guids = HID_PASS+1; + nb_guids = DEV_PASS+1; unref_list = (libusb_device**) calloc(unref_size, sizeof(libusb_device*)); if (unref_list == NULL) { @@ -1392,8 +1330,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered for (pass = 0; ((pass < nb_guids) && (r == LIBUSB_SUCCESS)); pass++) { //#define ENUM_DEBUG #ifdef ENUM_DEBUG - const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "HID", "EXT" }; - usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=HID_PASS)?pass:HID_PASS+1], + const char *passname[] = { "HCD", "HUB", "GEN", "DEV", "EXT" }; + usbi_dbg("\n#### PROCESSING %ss %s", passname[(pass<=DEV_PASS)?pass:DEV_PASS+1], (pass!=GEN_PASS)?guid_to_string(guid[pass]):""); #endif for (i = 0; ; i++) { @@ -1501,9 +1439,6 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered } } break; - case HID_PASS: - api = USB_API_HID; - break; default: // Get the API type (after checking that the driver installation is OK) if ( (!pSetupDiGetDeviceRegistryPropertyA(dev_info, &dev_info_data, SPDRP_INSTALL_STATE, @@ -1606,13 +1541,6 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered case USB_API_COMPOSITE: case USB_API_HUB: break; - case USB_API_HID: - priv->hid = calloc(1, sizeof(struct hid_device_priv)); - if (priv->hid == NULL) { - LOOP_BREAK(LIBUSB_ERROR_NO_MEM); - } - priv->hid->nb_interfaces = 0; - break; default: // For other devices, the first interface is the same as the device priv->usb_interface[0].path = (char*) calloc(safe_strlen(priv->path)+1, 1); @@ -1644,13 +1572,8 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered r = LIBUSB_SUCCESS; } break; - default: // HID_PASS and later - if (parent_priv->apib->id == USB_API_HID) { - usbi_dbg("setting HID interface for [%lX]:", parent_dev->session_data); - r = set_hid_interface(ctx, parent_dev, dev_interface_path); - if (r != LIBUSB_SUCCESS) LOOP_BREAK(r); - dev_interface_path = NULL; - } else if (parent_priv->apib->id == USB_API_COMPOSITE) { + default: // later passes + if (parent_priv->apib->id == USB_API_COMPOSITE) { usbi_dbg("setting composite interface for [%lX]:", parent_dev->session_data); switch (set_composite_interface(ctx, parent_dev, dev_interface_path, dev_id_path, api, sub_api)) { case LIBUSB_SUCCESS: @@ -1670,7 +1593,7 @@ static int windows_get_device_list(struct libusb_context *ctx, struct discovered } // Free any additional GUIDs - for (pass = HID_PASS+1; pass < nb_guids; pass++) { + for (pass = DEV_PASS+1; pass < nb_guids; pass++) { safe_free(guid[pass]); } @@ -1927,7 +1850,6 @@ static void windows_clear_transfer_priv(struct usbi_transfer *itransfer) struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); usbi_free_fd(&transfer_priv->pollable_fd); - safe_free(transfer_priv->hid_buffer); // When auto claim is in use, attempt to release the auto-claimed interface auto_release(itransfer); } @@ -2388,7 +2310,6 @@ static int common_configure_endpoints(int sub_api, struct libusb_device_handle * const char* hub_driver_names[] = {"USBHUB", "USBHUB3", "NUSB3HUB", "RUSB3HUB", "FLXHCIH", "TIHUB3", "ETRONHUB3", "VIAHUB3", "ASMTHUB3", "IUSB3HUB"}; const char* composite_driver_names[] = {"USBCCGP"}; const char* winusbx_driver_names[] = WINUSBX_DRV_NAMES; -const char* hid_driver_names[] = {"HIDUSB", "MOUHID", "KBDHID"}; const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { { USB_API_UNSUPPORTED, @@ -2474,27 +2395,6 @@ const struct windows_usb_api_backend usb_api_backend[USB_API_MAX] = { winusbx_abort_control, winusbx_abort_transfers, winusbx_copy_transfer_data, - }, { - USB_API_HID, - "HID API", - hid_driver_names, - ARRAYSIZE(hid_driver_names), - hid_init, - hid_exit, - hid_open, - hid_close, - common_configure_endpoints, - hid_claim_interface, - hid_set_interface_altsetting, - hid_release_interface, - hid_clear_halt, - hid_reset_device, - hid_submit_bulk_transfer, - unsupported_submit_iso_transfer, - hid_submit_control_transfer, - hid_abort_transfers, - hid_abort_transfers, - hid_copy_transfer_data, }, }; @@ -2825,7 +2725,7 @@ static int get_valid_interface(struct libusb_device_handle *dev_handle, int api_ struct windows_device_priv *priv = _device_priv(dev_handle->dev); int i; - if ((api_id < USB_API_WINUSBX) || (api_id > USB_API_HID)) { + if ((api_id < USB_API_WINUSBX) || (api_id >= USB_API_MAX)) { usbi_dbg("unsupported API ID"); return -1; } @@ -3153,1043 +3053,6 @@ static int winusbx_copy_transfer_data(int sub_api, struct usbi_transfer *itransf } /* - * Internal HID Support functions (from libusb-win32) - * Note that functions that complete data transfer synchronously must return - * LIBUSB_COMPLETED instead of LIBUSB_SUCCESS - */ -static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size); -static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size); - -static int _hid_wcslen(WCHAR *str) -{ - int i = 0; - while (str[i] && (str[i] != 0x409)) { - i++; - } - return i; -} - -static int _hid_get_device_descriptor(struct hid_device_priv* dev, void *data, size_t *size) -{ - struct libusb_device_descriptor d; - - d.bLength = LIBUSB_DT_DEVICE_SIZE; - d.bDescriptorType = LIBUSB_DT_DEVICE; - d.bcdUSB = 0x0200; /* 2.00 */ - d.bDeviceClass = 0; - d.bDeviceSubClass = 0; - d.bDeviceProtocol = 0; - d.bMaxPacketSize0 = 64; /* fix this! */ - d.idVendor = (uint16_t)dev->vid; - d.idProduct = (uint16_t)dev->pid; - d.bcdDevice = 0x0100; - d.iManufacturer = dev->string_index[0]; - d.iProduct = dev->string_index[1]; - d.iSerialNumber = dev->string_index[2]; - d.bNumConfigurations = 1; - - if (*size > LIBUSB_DT_DEVICE_SIZE) - *size = LIBUSB_DT_DEVICE_SIZE; - memcpy(data, &d, *size); - return LIBUSB_COMPLETED; -} - -static int _hid_get_config_descriptor(struct hid_device_priv* dev, void *data, size_t *size) -{ - char num_endpoints = 0; - size_t config_total_len = 0; - char tmp[HID_MAX_CONFIG_DESC_SIZE]; - struct libusb_config_descriptor *cd; - struct libusb_interface_descriptor *id; - struct libusb_hid_descriptor *hd; - struct libusb_endpoint_descriptor *ed; - size_t tmp_size; - - if (dev->input_report_size) - num_endpoints++; - if (dev->output_report_size) - num_endpoints++; - - config_total_len = LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE - + LIBUSB_DT_HID_SIZE + num_endpoints * LIBUSB_DT_ENDPOINT_SIZE; - - - cd = (struct libusb_config_descriptor *)tmp; - id = (struct libusb_interface_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE); - hd = (struct libusb_hid_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE - + LIBUSB_DT_INTERFACE_SIZE); - ed = (struct libusb_endpoint_descriptor *)(tmp + LIBUSB_DT_CONFIG_SIZE - + LIBUSB_DT_INTERFACE_SIZE - + LIBUSB_DT_HID_SIZE); - - cd->bLength = LIBUSB_DT_CONFIG_SIZE; - cd->bDescriptorType = LIBUSB_DT_CONFIG; - cd->wTotalLength = (uint16_t) config_total_len; - cd->bNumInterfaces = 1; - cd->bConfigurationValue = 1; - cd->iConfiguration = 0; - cd->bmAttributes = 1 << 7; /* bus powered */ - cd->MaxPower = 50; - - id->bLength = LIBUSB_DT_INTERFACE_SIZE; - id->bDescriptorType = LIBUSB_DT_INTERFACE; - id->bInterfaceNumber = 0; - id->bAlternateSetting = 0; - id->bNumEndpoints = num_endpoints; - id->bInterfaceClass = 3; - id->bInterfaceSubClass = 0; - id->bInterfaceProtocol = 0; - id->iInterface = 0; - - tmp_size = LIBUSB_DT_HID_SIZE; - _hid_get_hid_descriptor(dev, hd, &tmp_size); - - if (dev->input_report_size) { - ed->bLength = LIBUSB_DT_ENDPOINT_SIZE; - ed->bDescriptorType = LIBUSB_DT_ENDPOINT; - ed->bEndpointAddress = HID_IN_EP; - ed->bmAttributes = 3; - ed->wMaxPacketSize = dev->input_report_size - 1; - ed->bInterval = 10; - ed = (struct libusb_endpoint_descriptor *)((char*)ed + LIBUSB_DT_ENDPOINT_SIZE); - } - - if (dev->output_report_size) { - ed->bLength = LIBUSB_DT_ENDPOINT_SIZE; - ed->bDescriptorType = LIBUSB_DT_ENDPOINT; - ed->bEndpointAddress = HID_OUT_EP; - ed->bmAttributes = 3; - ed->wMaxPacketSize = dev->output_report_size - 1; - ed->bInterval = 10; - } - - if (*size > config_total_len) - *size = config_total_len; - memcpy(data, tmp, *size); - return LIBUSB_COMPLETED; -} - -static int _hid_get_string_descriptor(struct hid_device_priv* dev, int _index, - void *data, size_t *size) -{ - void *tmp = NULL; - size_t tmp_size = 0; - int i; - - /* language ID, EN-US */ - char string_langid[] = { - 0x09, - 0x04 - }; - - if ((*size < 2) || (*size > 255)) { - return LIBUSB_ERROR_OVERFLOW; - } - - if (_index == 0) { - tmp = string_langid; - tmp_size = sizeof(string_langid)+2; - } else { - for (i=0; i<3; i++) { - if (_index == (dev->string_index[i])) { - tmp = dev->string[i]; - tmp_size = (_hid_wcslen(dev->string[i])+1) * sizeof(WCHAR); - break; - } - } - if (i == 3) { // not found - return LIBUSB_ERROR_INVALID_PARAM; - } - } - - if(!tmp_size) { - return LIBUSB_ERROR_INVALID_PARAM; - } - - if (tmp_size < *size) { - *size = tmp_size; - } - // 2 byte header - ((uint8_t*)data)[0] = (uint8_t)*size; - ((uint8_t*)data)[1] = LIBUSB_DT_STRING; - memcpy((uint8_t*)data+2, tmp, *size-2); - return LIBUSB_COMPLETED; -} - -static int _hid_get_hid_descriptor(struct hid_device_priv* dev, void *data, size_t *size) -{ - struct libusb_hid_descriptor d; - uint8_t tmp[MAX_HID_DESCRIPTOR_SIZE]; - size_t report_len = MAX_HID_DESCRIPTOR_SIZE; - - _hid_get_report_descriptor(dev, tmp, &report_len); - - d.bLength = LIBUSB_DT_HID_SIZE; - d.bDescriptorType = LIBUSB_DT_HID; - d.bcdHID = 0x0110; /* 1.10 */ - d.bCountryCode = 0; - d.bNumDescriptors = 1; - d.bClassDescriptorType = LIBUSB_DT_REPORT; - d.wClassDescriptorLength = (uint16_t)report_len; - - if (*size > LIBUSB_DT_HID_SIZE) - *size = LIBUSB_DT_HID_SIZE; - memcpy(data, &d, *size); - return LIBUSB_COMPLETED; -} - -static int _hid_get_report_descriptor(struct hid_device_priv* dev, void *data, size_t *size) -{ - uint8_t d[MAX_HID_DESCRIPTOR_SIZE]; - size_t i = 0; - - /* usage page (0xFFA0 == vendor defined) */ - d[i++] = 0x06; d[i++] = 0xA0; d[i++] = 0xFF; - /* usage (vendor defined) */ - d[i++] = 0x09; d[i++] = 0x01; - /* start collection (application) */ - d[i++] = 0xA1; d[i++] = 0x01; - /* input report */ - if (dev->input_report_size) { - /* usage (vendor defined) */ - d[i++] = 0x09; d[i++] = 0x01; - /* logical minimum (0) */ - d[i++] = 0x15; d[i++] = 0x00; - /* logical maximum (255) */ - d[i++] = 0x25; d[i++] = 0xFF; - /* report size (8 bits) */ - d[i++] = 0x75; d[i++] = 0x08; - /* report count */ - d[i++] = 0x95; d[i++] = (uint8_t)dev->input_report_size - 1; - /* input (data, variable, absolute) */ - d[i++] = 0x81; d[i++] = 0x00; - } - /* output report */ - if (dev->output_report_size) { - /* usage (vendor defined) */ - d[i++] = 0x09; d[i++] = 0x02; - /* logical minimum (0) */ - d[i++] = 0x15; d[i++] = 0x00; - /* logical maximum (255) */ - d[i++] = 0x25; d[i++] = 0xFF; - /* report size (8 bits) */ - d[i++] = 0x75; d[i++] = 0x08; - /* report count */ - d[i++] = 0x95; d[i++] = (uint8_t)dev->output_report_size - 1; - /* output (data, variable, absolute) */ - d[i++] = 0x91; d[i++] = 0x00; - } - /* feature report */ - if (dev->feature_report_size) { - /* usage (vendor defined) */ - d[i++] = 0x09; d[i++] = 0x03; - /* logical minimum (0) */ - d[i++] = 0x15; d[i++] = 0x00; - /* logical maximum (255) */ - d[i++] = 0x25; d[i++] = 0xFF; - /* report size (8 bits) */ - d[i++] = 0x75; d[i++] = 0x08; - /* report count */ - d[i++] = 0x95; d[i++] = (uint8_t)dev->feature_report_size - 1; - /* feature (data, variable, absolute) */ - d[i++] = 0xb2; d[i++] = 0x02; d[i++] = 0x01; - } - - /* end collection */ - d[i++] = 0xC0; - - if (*size > i) - *size = i; - memcpy(data, d, *size); - return LIBUSB_COMPLETED; -} - -static int _hid_get_descriptor(struct hid_device_priv* dev, HANDLE hid_handle, int recipient, - int type, int _index, void *data, size_t *size) -{ - switch(type) { - case LIBUSB_DT_DEVICE: - usbi_dbg("LIBUSB_DT_DEVICE"); - return _hid_get_device_descriptor(dev, data, size); - case LIBUSB_DT_CONFIG: - usbi_dbg("LIBUSB_DT_CONFIG"); - if (!_index) - return _hid_get_config_descriptor(dev, data, size); - return LIBUSB_ERROR_INVALID_PARAM; - case LIBUSB_DT_STRING: - usbi_dbg("LIBUSB_DT_STRING"); - return _hid_get_string_descriptor(dev, _index, data, size); - case LIBUSB_DT_HID: - usbi_dbg("LIBUSB_DT_HID"); - if (!_index) - return _hid_get_hid_descriptor(dev, data, size); - return LIBUSB_ERROR_INVALID_PARAM; - case LIBUSB_DT_REPORT: - usbi_dbg("LIBUSB_DT_REPORT"); - if (!_index) - return _hid_get_report_descriptor(dev, data, size); - return LIBUSB_ERROR_INVALID_PARAM; - case LIBUSB_DT_PHYSICAL: - usbi_dbg("LIBUSB_DT_PHYSICAL"); - if (HidD_GetPhysicalDescriptor(hid_handle, data, (ULONG)*size)) - return LIBUSB_COMPLETED; - return LIBUSB_ERROR_OTHER; - } - usbi_dbg("unsupported"); - return LIBUSB_ERROR_INVALID_PARAM; -} - -static int _hid_get_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, - struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped, - int report_type) -{ - uint8_t *buf; - DWORD ioctl_code, read_size, expected_size = (DWORD)*size; - int r = LIBUSB_SUCCESS; - - if (tp->hid_buffer != NULL) { - usbi_dbg("program assertion failed: hid_buffer is not NULL"); - } - - if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) { - usbi_dbg("invalid size (%d)", *size); - return LIBUSB_ERROR_INVALID_PARAM; - } - - switch (report_type) { - case HID_REPORT_TYPE_INPUT: - ioctl_code = IOCTL_HID_GET_INPUT_REPORT; - break; - case HID_REPORT_TYPE_FEATURE: - ioctl_code = IOCTL_HID_GET_FEATURE; - break; - default: - usbi_dbg("unknown HID report type %d", report_type); - return LIBUSB_ERROR_INVALID_PARAM; - } - - // Add a trailing byte to detect overflows - buf = (uint8_t*)calloc(expected_size+1, 1); - if (buf == NULL) { - return LIBUSB_ERROR_NO_MEM; - } - buf[0] = (uint8_t)id; // Must be set always - usbi_dbg("report ID: 0x%02X", buf[0]); - - tp->hid_expected_size = expected_size; - read_size = expected_size; - - // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0) - if (!DeviceIoControl(hid_handle, ioctl_code, buf, expected_size+1, - buf, expected_size+1, &read_size, overlapped)) { - if (GetLastError() != ERROR_IO_PENDING) { - usbi_dbg("Failed to Read HID Report: %s", windows_error_str(0)); - safe_free(buf); - return LIBUSB_ERROR_IO; - } - // Asynchronous wait - tp->hid_buffer = buf; - tp->hid_dest = (uint8_t*)data; // copy dest, as not necessarily the start of the transfer buffer - return LIBUSB_SUCCESS; - } - - // Transfer completed synchronously => copy and discard extra buffer - if (read_size == 0) { - usbi_warn(NULL, "program assertion failed - read completed synchronously, but no data was read"); - *size = 0; - } else { - if (buf[0] != id) { - usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id); - } - if ((size_t)read_size > expected_size) { - r = LIBUSB_ERROR_OVERFLOW; - usbi_dbg("OVERFLOW!"); - } else { - r = LIBUSB_COMPLETED; - } - - *size = MIN((size_t)read_size, *size); - if (id == 0) { - // Discard report ID - memcpy(data, buf+1, *size); - } else { - memcpy(data, buf, *size); - } - } - safe_free(buf); - return r; -} - -static int _hid_set_report(struct hid_device_priv* dev, HANDLE hid_handle, int id, void *data, - struct windows_transfer_priv *tp, size_t *size, OVERLAPPED* overlapped, - int report_type) -{ - uint8_t *buf = NULL; - DWORD ioctl_code, write_size= (DWORD)*size; - - if (tp->hid_buffer != NULL) { - usbi_dbg("program assertion failed: hid_buffer is not NULL"); - } - - if ((*size == 0) || (*size > MAX_HID_REPORT_SIZE)) { - usbi_dbg("invalid size (%d)", *size); - return LIBUSB_ERROR_INVALID_PARAM; - } - - switch (report_type) { - case HID_REPORT_TYPE_OUTPUT: - ioctl_code = IOCTL_HID_SET_OUTPUT_REPORT; - break; - case HID_REPORT_TYPE_FEATURE: - ioctl_code = IOCTL_HID_SET_FEATURE; - break; - default: - usbi_dbg("unknown HID report type %d", report_type); - return LIBUSB_ERROR_INVALID_PARAM; - } - - usbi_dbg("report ID: 0x%02X", id); - // When report IDs are not used (i.e. when id == 0), we must add - // a null report ID. Otherwise, we just use original data buffer - if (id == 0) { - write_size++; - } - buf = (uint8_t*) malloc(write_size); - if (buf == NULL) { - return LIBUSB_ERROR_NO_MEM; - } - if (id == 0) { - buf[0] = 0; - memcpy(buf + 1, data, *size); - } else { - // This seems like a waste, but if we don't duplicate the - // data, we'll get issues when freeing hid_buffer - memcpy(buf, data, *size); - if (buf[0] != id) { - usbi_warn(NULL, "mismatched report ID (data is %02X, parameter is %02X)", buf[0], id); - } - } - - // NB: The size returned by DeviceIoControl doesn't include report IDs when not in use (0) - if (!DeviceIoControl(hid_handle, ioctl_code, buf, write_size, - buf, write_size, &write_size, overlapped)) { - if (GetLastError() != ERROR_IO_PENDING) { - usbi_dbg("Failed to Write HID Output Report: %s", windows_error_str(0)); - safe_free(buf); - return LIBUSB_ERROR_IO; - } - tp->hid_buffer = buf; - tp->hid_dest = NULL; - return LIBUSB_SUCCESS; - } - - // Transfer completed synchronously - *size = write_size; - if (write_size == 0) { - usbi_dbg("program assertion failed - write completed synchronously, but no data was written"); - } - safe_free(buf); - return LIBUSB_COMPLETED; -} - -static int _hid_class_request(struct hid_device_priv* dev, HANDLE hid_handle, int request_type, - int request, int value, int _index, void *data, struct windows_transfer_priv *tp, - size_t *size, OVERLAPPED* overlapped) -{ - int report_type = (value >> 8) & 0xFF; - int report_id = value & 0xFF; - - if ( (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_INTERFACE) - && (LIBUSB_REQ_RECIPIENT(request_type) != LIBUSB_RECIPIENT_DEVICE) ) - return LIBUSB_ERROR_INVALID_PARAM; - - if (LIBUSB_REQ_OUT(request_type) && request == HID_REQ_SET_REPORT) - return _hid_set_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type); - - if (LIBUSB_REQ_IN(request_type) && request == HID_REQ_GET_REPORT) - return _hid_get_report(dev, hid_handle, report_id, data, tp, size, overlapped, report_type); - - return LIBUSB_ERROR_INVALID_PARAM; -} - - -/* - * HID API functions - */ -static int hid_init(int sub_api, struct libusb_context *ctx) -{ - DLL_LOAD(hid.dll, HidD_GetAttributes, TRUE); - DLL_LOAD(hid.dll, HidD_GetHidGuid, TRUE); - DLL_LOAD(hid.dll, HidD_GetPreparsedData, TRUE); - DLL_LOAD(hid.dll, HidD_FreePreparsedData, TRUE); - DLL_LOAD(hid.dll, HidD_GetManufacturerString, TRUE); - DLL_LOAD(hid.dll, HidD_GetProductString, TRUE); - DLL_LOAD(hid.dll, HidD_GetSerialNumberString, TRUE); - DLL_LOAD(hid.dll, HidP_GetCaps, TRUE); - DLL_LOAD(hid.dll, HidD_SetNumInputBuffers, TRUE); - DLL_LOAD(hid.dll, HidD_SetFeature, TRUE); - DLL_LOAD(hid.dll, HidD_GetFeature, TRUE); - DLL_LOAD(hid.dll, HidD_GetPhysicalDescriptor, TRUE); - DLL_LOAD(hid.dll, HidD_GetInputReport, FALSE); - DLL_LOAD(hid.dll, HidD_SetOutputReport, FALSE); - DLL_LOAD(hid.dll, HidD_FlushQueue, TRUE); - DLL_LOAD(hid.dll, HidP_GetValueCaps, TRUE); - - api_hid_available = true; - return LIBUSB_SUCCESS; -} - -static int hid_exit(int sub_api) -{ - return LIBUSB_SUCCESS; -} - -// NB: open and close must ensure that they only handle interface of -// the right API type, as these functions can be called wholesale from -// composite_open(), with interfaces belonging to different APIs -static int hid_open(int sub_api, struct libusb_device_handle *dev_handle) -{ - struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); - struct windows_device_priv *priv = _device_priv(dev_handle->dev); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - - HIDD_ATTRIBUTES hid_attributes; - PHIDP_PREPARSED_DATA preparsed_data = NULL; - HIDP_CAPS capabilities; - HIDP_VALUE_CAPS *value_caps; - - HANDLE hid_handle = INVALID_HANDLE_VALUE; - int i, j; - // report IDs handling - ULONG size[3]; - const char* type[3] = {"input", "output", "feature"}; - int nb_ids[2]; // zero and nonzero report IDs - - CHECK_HID_AVAILABLE; - if (priv->hid == NULL) { - usbi_err(ctx, "program assertion failed - private HID structure is unitialized"); - return LIBUSB_ERROR_NOT_FOUND; - } - - for (i = 0; i < USB_MAXINTERFACES; i++) { - if ( (priv->usb_interface[i].path != NULL) - && (priv->usb_interface[i].apib->id == USB_API_HID) ) { - hid_handle = CreateFileA(priv->usb_interface[i].path, GENERIC_WRITE | GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); - /* - * http://www.lvr.com/hidfaq.htm: Why do I receive "Access denied" when attempting to access my HID? - * "Windows 2000 and later have exclusive read/write access to HIDs that are configured as a system - * keyboards or mice. An application can obtain a handle to a system keyboard or mouse by not - * requesting READ or WRITE access with CreateFile. Applications can then use HidD_SetFeature and - * HidD_GetFeature (if the device supports Feature reports)." - */ - if (hid_handle == INVALID_HANDLE_VALUE) { - usbi_warn(ctx, "could not open HID device in R/W mode (keyboard or mouse?) - trying without"); - hid_handle = CreateFileA(priv->usb_interface[i].path, 0, FILE_SHARE_WRITE | FILE_SHARE_READ, - NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL); - if (hid_handle == INVALID_HANDLE_VALUE) { - usbi_err(ctx, "could not open device %s (interface %d): %s", priv->path, i, windows_error_str(0)); - switch(GetLastError()) { - case ERROR_FILE_NOT_FOUND: // The device was disconnected - return LIBUSB_ERROR_NO_DEVICE; - case ERROR_ACCESS_DENIED: - return LIBUSB_ERROR_ACCESS; - default: - return LIBUSB_ERROR_IO; - } - } - priv->usb_interface[i].restricted_functionality = true; - } - handle_priv->interface_handle[i].api_handle = hid_handle; - } - } - - hid_attributes.Size = sizeof(hid_attributes); - do { - if (!HidD_GetAttributes(hid_handle, &hid_attributes)) { - usbi_err(ctx, "could not gain access to HID top collection (HidD_GetAttributes)"); - break; - } - - priv->hid->vid = hid_attributes.VendorID; - priv->hid->pid = hid_attributes.ProductID; - - // Set the maximum available input buffer size - for (i=32; HidD_SetNumInputBuffers(hid_handle, i); i*=2); - usbi_dbg("set maximum input buffer size to %d", i/2); - - // Get the maximum input and output report size - if (!HidD_GetPreparsedData(hid_handle, &preparsed_data) || !preparsed_data) { - usbi_err(ctx, "could not read HID preparsed data (HidD_GetPreparsedData)"); - break; - } - if (HidP_GetCaps(preparsed_data, &capabilities) != HIDP_STATUS_SUCCESS) { - usbi_err(ctx, "could not parse HID capabilities (HidP_GetCaps)"); - break; - } - - // Find out if interrupt will need report IDs - size[0] = capabilities.NumberInputValueCaps; - size[1] = capabilities.NumberOutputValueCaps; - size[2] = capabilities.NumberFeatureValueCaps; - for (j=HidP_Input; j<=HidP_Feature; j++) { - usbi_dbg("%d HID %s report value(s) found", size[j], type[j]); - priv->hid->uses_report_ids[j] = false; - if (size[j] > 0) { - value_caps = (HIDP_VALUE_CAPS*) calloc(size[j], sizeof(HIDP_VALUE_CAPS)); - if ( (value_caps != NULL) - && (HidP_GetValueCaps((HIDP_REPORT_TYPE)j, value_caps, &size[j], preparsed_data) == HIDP_STATUS_SUCCESS) - && (size[j] >= 1) ) { - nb_ids[0] = 0; - nb_ids[1] = 0; - for (i=0; i<(int)size[j]; i++) { - usbi_dbg(" Report ID: 0x%02X", value_caps[i].ReportID); - if (value_caps[i].ReportID != 0) { - nb_ids[1]++; - } else { - nb_ids[0]++; - } - } - if (nb_ids[1] != 0) { - if (nb_ids[0] != 0) { - usbi_warn(ctx, "program assertion failed: zero and nonzero report IDs used for %s", - type[j]); - } - priv->hid->uses_report_ids[j] = true; - } - } else { - usbi_warn(ctx, " could not process %s report IDs", type[j]); - } - safe_free(value_caps); - } - } - - // Set the report sizes - priv->hid->input_report_size = capabilities.InputReportByteLength; - priv->hid->output_report_size = capabilities.OutputReportByteLength; - priv->hid->feature_report_size = capabilities.FeatureReportByteLength; - - // Fetch string descriptors - priv->hid->string_index[0] = priv->dev_descriptor.iManufacturer; - if (priv->hid->string_index[0] != 0) { - HidD_GetManufacturerString(hid_handle, priv->hid->string[0], - sizeof(priv->hid->string[0])); - } else { - priv->hid->string[0][0] = 0; - } - priv->hid->string_index[1] = priv->dev_descriptor.iProduct; - if (priv->hid->string_index[1] != 0) { - HidD_GetProductString(hid_handle, priv->hid->string[1], - sizeof(priv->hid->string[1])); - } else { - priv->hid->string[1][0] = 0; - } - priv->hid->string_index[2] = priv->dev_descriptor.iSerialNumber; - if (priv->hid->string_index[2] != 0) { - HidD_GetSerialNumberString(hid_handle, priv->hid->string[2], - sizeof(priv->hid->string[2])); - } else { - priv->hid->string[2][0] = 0; - } - } while(0); - - if (preparsed_data) { - HidD_FreePreparsedData(preparsed_data); - } - - return LIBUSB_SUCCESS; -} - -static void hid_close(int sub_api, struct libusb_device_handle *dev_handle) -{ - struct windows_device_priv *priv = _device_priv(dev_handle->dev); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - HANDLE file_handle; - int i; - - if (!api_hid_available) - return; - - for (i = 0; i < USB_MAXINTERFACES; i++) { - if (priv->usb_interface[i].apib->id == USB_API_HID) { - file_handle = handle_priv->interface_handle[i].api_handle; - if ( (file_handle != 0) && (file_handle != INVALID_HANDLE_VALUE)) { - CloseHandle(file_handle); - } - } - } -} - -static int hid_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) -{ - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - struct windows_device_priv *priv = _device_priv(dev_handle->dev); - - CHECK_HID_AVAILABLE; - - // NB: Disconnection detection is not possible in this function - if (priv->usb_interface[iface].path == NULL) { - return LIBUSB_ERROR_NOT_FOUND; // invalid iface - } - - // We use dev_handle as a flag for interface claimed - if (handle_priv->interface_handle[iface].dev_handle == INTERFACE_CLAIMED) { - return LIBUSB_ERROR_BUSY; // already claimed - } - - handle_priv->interface_handle[iface].dev_handle = INTERFACE_CLAIMED; - - usbi_dbg("claimed interface %d", iface); - handle_priv->active_interface = iface; - - return LIBUSB_SUCCESS; -} - -static int hid_release_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) -{ - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - struct windows_device_priv *priv = _device_priv(dev_handle->dev); - - CHECK_HID_AVAILABLE; - - if (priv->usb_interface[iface].path == NULL) { - return LIBUSB_ERROR_NOT_FOUND; // invalid iface - } - - if (handle_priv->interface_handle[iface].dev_handle != INTERFACE_CLAIMED) { - return LIBUSB_ERROR_NOT_FOUND; // invalid iface - } - - handle_priv->interface_handle[iface].dev_handle = INVALID_HANDLE_VALUE; - - return LIBUSB_SUCCESS; -} - -static int hid_set_interface_altsetting(int sub_api, struct libusb_device_handle *dev_handle, int iface, int altsetting) -{ - struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); - - CHECK_HID_AVAILABLE; - - if (altsetting > 255) { - return LIBUSB_ERROR_INVALID_PARAM; - } - - if (altsetting != 0) { - usbi_err(ctx, "set interface altsetting not supported for altsetting >0"); - return LIBUSB_ERROR_NOT_SUPPORTED; - } - - return LIBUSB_SUCCESS; -} - -static int hid_submit_control_transfer(int sub_api, struct usbi_transfer *itransfer) -{ - struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); - struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); - struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); - WINUSB_SETUP_PACKET *setup = (WINUSB_SETUP_PACKET *) transfer->buffer; - HANDLE hid_handle; - struct winfd wfd; - int current_interface, config; - size_t size; - int r = LIBUSB_ERROR_INVALID_PARAM; - - CHECK_HID_AVAILABLE; - - transfer_priv->pollable_fd = INVALID_WINFD; - safe_free(transfer_priv->hid_buffer); - transfer_priv->hid_dest = NULL; - size = transfer->length - LIBUSB_CONTROL_SETUP_SIZE; - - if (size > MAX_CTRL_BUFFER_LENGTH) { - return LIBUSB_ERROR_INVALID_PARAM; - } - - current_interface = get_valid_interface(transfer->dev_handle, USB_API_HID); - if (current_interface < 0) { - if (auto_claim(transfer, ¤t_interface, USB_API_HID) != LIBUSB_SUCCESS) { - return LIBUSB_ERROR_NOT_FOUND; - } - } - - usbi_dbg("will use interface %d", current_interface); - hid_handle = handle_priv->interface_handle[current_interface].api_handle; - // Always use the handle returned from usbi_create_fd (wfd.handle) - wfd = usbi_create_fd(hid_handle, RW_READ, NULL, NULL); - if (wfd.fd < 0) { - return LIBUSB_ERROR_NOT_FOUND; - } - - switch(LIBUSB_REQ_TYPE(setup->request_type)) { - case LIBUSB_REQUEST_TYPE_STANDARD: - switch(setup->request) { - case LIBUSB_REQUEST_GET_DESCRIPTOR: - r = _hid_get_descriptor(priv->hid, wfd.handle, LIBUSB_REQ_RECIPIENT(setup->request_type), - (setup->value >> 8) & 0xFF, setup->value & 0xFF, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, &size); - break; - case LIBUSB_REQUEST_GET_CONFIGURATION: - r = windows_get_configuration(transfer->dev_handle, &config); - if (r == LIBUSB_SUCCESS) { - size = 1; - ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = (uint8_t)config; - r = LIBUSB_COMPLETED; - } - break; - case LIBUSB_REQUEST_SET_CONFIGURATION: - if (setup->value == priv->active_config) { - r = LIBUSB_COMPLETED; - } else { - usbi_warn(ctx, "cannot set configuration other than the default one"); - r = LIBUSB_ERROR_INVALID_PARAM; - } - break; - case LIBUSB_REQUEST_GET_INTERFACE: - size = 1; - ((uint8_t*)transfer->buffer)[LIBUSB_CONTROL_SETUP_SIZE] = 0; - r = LIBUSB_COMPLETED; - break; - case LIBUSB_REQUEST_SET_INTERFACE: - r = hid_set_interface_altsetting(0, transfer->dev_handle, setup->index, setup->value); - if (r == LIBUSB_SUCCESS) { - r = LIBUSB_COMPLETED; - } - break; - default: - usbi_warn(ctx, "unsupported HID control request"); - r = LIBUSB_ERROR_INVALID_PARAM; - break; - } - break; - case LIBUSB_REQUEST_TYPE_CLASS: - r =_hid_class_request(priv->hid, wfd.handle, setup->request_type, setup->request, setup->value, - setup->index, transfer->buffer + LIBUSB_CONTROL_SETUP_SIZE, transfer_priv, - &size, wfd.overlapped); - break; - default: - usbi_warn(ctx, "unsupported HID control request"); - r = LIBUSB_ERROR_INVALID_PARAM; - break; - } - - if (r == LIBUSB_COMPLETED) { - // Force request to be completed synchronously. Transferred size has been set by previous call - wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; - // http://msdn.microsoft.com/en-us/library/ms684342%28VS.85%29.aspx - // set InternalHigh to the number of bytes transferred - wfd.overlapped->InternalHigh = (DWORD)size; - r = LIBUSB_SUCCESS; - } - - if (r == LIBUSB_SUCCESS) { - // Use priv_transfer to store data needed for async polling - transfer_priv->pollable_fd = wfd; - transfer_priv->interface_number = (uint8_t)current_interface; - } else { - usbi_free_fd(&wfd); - } - - return r; -} - -static int hid_submit_bulk_transfer(int sub_api, struct usbi_transfer *itransfer) { - struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); - struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); - struct windows_device_priv *priv = _device_priv(transfer->dev_handle->dev); - struct winfd wfd; - HANDLE hid_handle; - bool direction_in, ret; - int current_interface, length; - DWORD size; - int r = LIBUSB_SUCCESS; - - CHECK_HID_AVAILABLE; - - transfer_priv->pollable_fd = INVALID_WINFD; - transfer_priv->hid_dest = NULL; - safe_free(transfer_priv->hid_buffer); - - current_interface = interface_by_endpoint(priv, handle_priv, transfer->endpoint); - if (current_interface < 0) { - usbi_err(ctx, "unable to match endpoint to an open interface - cancelling transfer"); - return LIBUSB_ERROR_NOT_FOUND; - } - - usbi_dbg("matched endpoint %02X with interface %d", transfer->endpoint, current_interface); - - hid_handle = handle_priv->interface_handle[current_interface].api_handle; - direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN; - - wfd = usbi_create_fd(hid_handle, direction_in?RW_READ:RW_WRITE, NULL, NULL); - // Always use the handle returned from usbi_create_fd (wfd.handle) - if (wfd.fd < 0) { - return LIBUSB_ERROR_NO_MEM; - } - - // If report IDs are not in use, an extra prefix byte must be added - if ( ((direction_in) && (!priv->hid->uses_report_ids[0])) - || ((!direction_in) && (!priv->hid->uses_report_ids[1])) ) { - length = transfer->length+1; - } else { - length = transfer->length; - } - // Add a trailing byte to detect overflows on input - transfer_priv->hid_buffer = (uint8_t*)calloc(length+1, 1); - if (transfer_priv->hid_buffer == NULL) { - return LIBUSB_ERROR_NO_MEM; - } - transfer_priv->hid_expected_size = length; - - if (direction_in) { - transfer_priv->hid_dest = transfer->buffer; - usbi_dbg("reading %d bytes (report ID: 0x00)", length); - ret = ReadFile(wfd.handle, transfer_priv->hid_buffer, length+1, &size, wfd.overlapped); - } else { - if (!priv->hid->uses_report_ids[1]) { - memcpy(transfer_priv->hid_buffer+1, transfer->buffer, transfer->length); - } else { - // We could actually do without the calloc and memcpy in this case - memcpy(transfer_priv->hid_buffer, transfer->buffer, transfer->length); - } - usbi_dbg("writing %d bytes (report ID: 0x%02X)", length, transfer_priv->hid_buffer[0]); - ret = WriteFile(wfd.handle, transfer_priv->hid_buffer, length, &size, wfd.overlapped); - } - if (!ret) { - if (GetLastError() != ERROR_IO_PENDING) { - usbi_err(ctx, "HID transfer failed: %s", windows_error_str(0)); - usbi_free_fd(&wfd); - safe_free(transfer_priv->hid_buffer); - return LIBUSB_ERROR_IO; - } - } else { - // Only write operations that completed synchronously need to free up - // hid_buffer. For reads, copy_transfer_data() handles that process. - if (!direction_in) { - safe_free(transfer_priv->hid_buffer); - } - if (size == 0) { - usbi_err(ctx, "program assertion failed - no data was transferred"); - size = 1; - } - if (size > (size_t)length) { - usbi_err(ctx, "OVERFLOW!"); - r = LIBUSB_ERROR_OVERFLOW; - } - wfd.overlapped->Internal = STATUS_COMPLETED_SYNCHRONOUSLY; - wfd.overlapped->InternalHigh = size; - } - - transfer_priv->pollable_fd = wfd; - transfer_priv->interface_number = (uint8_t)current_interface; - - return r; -} - -static int hid_abort_transfers(int sub_api, struct usbi_transfer *itransfer) -{ - struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - struct windows_transfer_priv *transfer_priv = (struct windows_transfer_priv*)usbi_transfer_get_os_priv(itransfer); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(transfer->dev_handle); - HANDLE hid_handle; - int current_interface; - - CHECK_HID_AVAILABLE; - - current_interface = transfer_priv->interface_number; - hid_handle = handle_priv->interface_handle[current_interface].api_handle; - CancelIo(hid_handle); - - return LIBUSB_SUCCESS; -} - -static int hid_reset_device(int sub_api, struct libusb_device_handle *dev_handle) -{ - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - HANDLE hid_handle; - int current_interface; - - CHECK_HID_AVAILABLE; - - // Flushing the queues on all interfaces is the best we can achieve - for (current_interface = 0; current_interface < USB_MAXINTERFACES; current_interface++) { - hid_handle = handle_priv->interface_handle[current_interface].api_handle; - if ((hid_handle != 0) && (hid_handle != INVALID_HANDLE_VALUE)) { - HidD_FlushQueue(hid_handle); - } - } - return LIBUSB_SUCCESS; -} - -static int hid_clear_halt(int sub_api, struct libusb_device_handle *dev_handle, unsigned char endpoint) -{ - struct libusb_context *ctx = DEVICE_CTX(dev_handle->dev); - struct windows_device_handle_priv *handle_priv = _device_handle_priv(dev_handle); - struct windows_device_priv *priv = _device_priv(dev_handle->dev); - HANDLE hid_handle; - int current_interface; - - CHECK_HID_AVAILABLE; - - current_interface = interface_by_endpoint(priv, handle_priv, endpoint); - if (current_interface < 0) { - usbi_err(ctx, "unable to match endpoint to an open interface - cannot clear"); - return LIBUSB_ERROR_NOT_FOUND; - } - - usbi_dbg("matched endpoint %02X with interface %d", endpoint, current_interface); - hid_handle = handle_priv->interface_handle[current_interface].api_handle; - - // No endpoint selection with Microsoft's implementation, so we try to flush the - // whole interface. Should be OK for most case scenarios - if (!HidD_FlushQueue(hid_handle)) { - usbi_err(ctx, "Flushing of HID queue failed: %s", windows_error_str(0)); - // Device was probably disconnected - return LIBUSB_ERROR_NO_DEVICE; - } - - return LIBUSB_SUCCESS; -} - -// This extra function is only needed for HID -static int hid_copy_transfer_data(int sub_api, struct usbi_transfer *itransfer, uint32_t io_size) { - struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer); - struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev); - struct windows_transfer_priv *transfer_priv = usbi_transfer_get_os_priv(itransfer); - int r = LIBUSB_TRANSFER_COMPLETED; - uint32_t corrected_size = io_size; - - if (transfer_priv->hid_buffer != NULL) { - // If we have a valid hid_buffer, it means the transfer was async - if (transfer_priv->hid_dest != NULL) { // Data readout - // First, check for overflow - if (corrected_size > transfer_priv->hid_expected_size) { - usbi_err(ctx, "OVERFLOW!"); - corrected_size = (uint32_t)transfer_priv->hid_expected_size; - r = LIBUSB_TRANSFER_OVERFLOW; - } - - if (transfer_priv->hid_buffer[0] == 0) { - // Discard the 1 byte report ID prefix - corrected_size--; - memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer+1, corrected_size); - } else { - memcpy(transfer_priv->hid_dest, transfer_priv->hid_buffer, corrected_size); - } - transfer_priv->hid_dest = NULL; - } - // For write, we just need to free the hid buffer - safe_free(transfer_priv->hid_buffer); - } - itransfer->transferred += corrected_size; - return r; -} - - -/* * Composite API functions */ static int composite_init(int sub_api, struct libusb_context *ctx) @@ -4207,8 +3070,7 @@ static int composite_open(int sub_api, struct libusb_device_handle *dev_handle) struct windows_device_priv *priv = _device_priv(dev_handle->dev); int r = LIBUSB_ERROR_NOT_FOUND; uint8_t i; - // SUB_API_MAX+1 as the SUB_API_MAX pos is used to indicate availability of HID - bool available[SUB_API_MAX+1] = {0}; + bool available[SUB_API_MAX] = {0}; for (i=0; i<USB_MAXINTERFACES; i++) { switch (priv->usb_interface[i].apib->id) { @@ -4216,9 +3078,6 @@ static int composite_open(int sub_api, struct libusb_device_handle *dev_handle) if (priv->usb_interface[i].sub_api != SUB_API_NOTSET) available[priv->usb_interface[i].sub_api] = true; break; - case USB_API_HID: - available[SUB_API_MAX] = true; - break; default: break; } @@ -4232,9 +3091,6 @@ static int composite_open(int sub_api, struct libusb_device_handle *dev_handle) } } } - if (available[SUB_API_MAX]) { // HID driver - r = hid_open(SUB_API_NOTSET, dev_handle); - } return r; } @@ -4243,7 +3099,6 @@ static void composite_close(int sub_api, struct libusb_device_handle *dev_handle struct windows_device_priv *priv = _device_priv(dev_handle->dev); uint8_t i; bool available[SUB_API_MAX]; - bool has_hid = false; for (i = 0; i<SUB_API_MAX; i++) { available[i] = false; @@ -4253,8 +3108,6 @@ static void composite_close(int sub_api, struct libusb_device_handle *dev_handle if ( (priv->usb_interface[i].apib->id == USB_API_WINUSBX) && (priv->usb_interface[i].sub_api != SUB_API_NOTSET) ) { available[priv->usb_interface[i].sub_api] = true; - } else if (priv->usb_interface[i].apib->id == USB_API_HID) { - has_hid = true; } } @@ -4263,10 +3116,6 @@ static void composite_close(int sub_api, struct libusb_device_handle *dev_handle usb_api_backend[USB_API_WINUSBX].close(i, dev_handle); } } - - if (has_hid) { - usb_api_backend[USB_API_HID].close(sub_api, dev_handle); - } } static int composite_claim_interface(int sub_api, struct libusb_device_handle *dev_handle, int iface) diff --git a/chromium/third_party/libusb/src/libusb/os/windows_usb.h b/chromium/third_party/libusb/src/libusb/os/windows_usb.h index 5d67a562e80..97c8047cd12 100644 --- a/chromium/third_party/libusb/src/libusb/os/windows_usb.h +++ b/chromium/third_party/libusb/src/libusb/os/windows_usb.h @@ -52,19 +52,12 @@ extern char *_strdup(const char *strSource); #define MAX_CTRL_BUFFER_LENGTH 4096 #define MAX_USB_DEVICES 256 #define MAX_USB_STRING_LENGTH 128 -#define MAX_HID_REPORT_SIZE 1024 -#define MAX_HID_DESCRIPTOR_SIZE 256 #define MAX_GUID_STRING_LENGTH 40 #define MAX_PATH_LENGTH 128 #define MAX_KEY_LENGTH 256 #define LIST_SEPARATOR ';' #define HTAB_SIZE 1021 -// Handle code for HID interface that have been claimed ("dibs") -#define INTERFACE_CLAIMED ((HANDLE)(intptr_t)0xD1B5) -// Additional return code for HID operations that completed synchronously -#define LIBUSB_COMPLETED (LIBUSB_SUCCESS + 1) - // http://msdn.microsoft.com/en-us/library/ff545978.aspx // http://msdn.microsoft.com/en-us/library/ff545972.aspx // http://msdn.microsoft.com/en-us/library/ff545982.aspx @@ -89,9 +82,8 @@ const GUID GUID_DEVINTERFACE_LIBUSB0_FILTER = { 0xF9F3FF14, 0xAE21, 0x48A0, {0x8 #define USB_API_HUB 1 #define USB_API_COMPOSITE 2 #define USB_API_WINUSBX 3 -#define USB_API_HID 4 -#define USB_API_MAX 5 -// The following is used to indicate if the HID or composite extra props have already been set. +#define USB_API_MAX 4 +// The following is used to indicate if the composite extra props have already been set. #define USB_API_SET (1<<USB_API_MAX) // Sub-APIs for WinUSB-like driver APIs (WinUSB, libusbK, libusb-win32 through the libusbK DLL) @@ -139,70 +131,11 @@ extern const struct windows_usb_api_backend usb_api_backend[USB_API_MAX]; * with inline pseudo constructors/destructors */ -// TODO (v2+): move hid desc to libusb.h? -struct libusb_hid_descriptor { - uint8_t bLength; - uint8_t bDescriptorType; - uint16_t bcdHID; - uint8_t bCountryCode; - uint8_t bNumDescriptors; - uint8_t bClassDescriptorType; - uint16_t wClassDescriptorLength; -}; -#define LIBUSB_DT_HID_SIZE 9 -#define HID_MAX_CONFIG_DESC_SIZE (LIBUSB_DT_CONFIG_SIZE + LIBUSB_DT_INTERFACE_SIZE \ - + LIBUSB_DT_HID_SIZE + 2 * LIBUSB_DT_ENDPOINT_SIZE) -#define HID_MAX_REPORT_SIZE 1024 -#define HID_IN_EP 0x81 -#define HID_OUT_EP 0x02 #define LIBUSB_REQ_RECIPIENT(request_type) ((request_type) & 0x1F) #define LIBUSB_REQ_TYPE(request_type) ((request_type) & (0x03 << 5)) #define LIBUSB_REQ_IN(request_type) ((request_type) & LIBUSB_ENDPOINT_IN) #define LIBUSB_REQ_OUT(request_type) (!LIBUSB_REQ_IN(request_type)) -// The following are used for HID reports IOCTLs -#define HID_CTL_CODE(id) \ - CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_NEITHER, FILE_ANY_ACCESS) -#define HID_BUFFER_CTL_CODE(id) \ - CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_BUFFERED, FILE_ANY_ACCESS) -#define HID_IN_CTL_CODE(id) \ - CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_IN_DIRECT, FILE_ANY_ACCESS) -#define HID_OUT_CTL_CODE(id) \ - CTL_CODE (FILE_DEVICE_KEYBOARD, (id), METHOD_OUT_DIRECT, FILE_ANY_ACCESS) - -#define IOCTL_HID_GET_FEATURE HID_OUT_CTL_CODE(100) -#define IOCTL_HID_GET_INPUT_REPORT HID_OUT_CTL_CODE(104) -#define IOCTL_HID_SET_FEATURE HID_IN_CTL_CODE(100) -#define IOCTL_HID_SET_OUTPUT_REPORT HID_IN_CTL_CODE(101) - -enum libusb_hid_request_type { - HID_REQ_GET_REPORT = 0x01, - HID_REQ_GET_IDLE = 0x02, - HID_REQ_GET_PROTOCOL = 0x03, - HID_REQ_SET_REPORT = 0x09, - HID_REQ_SET_IDLE = 0x0A, - HID_REQ_SET_PROTOCOL = 0x0B -}; - -enum libusb_hid_report_type { - HID_REPORT_TYPE_INPUT = 0x01, - HID_REPORT_TYPE_OUTPUT = 0x02, - HID_REPORT_TYPE_FEATURE = 0x03 -}; - -struct hid_device_priv { - uint16_t vid; - uint16_t pid; - uint8_t config; - uint8_t nb_interfaces; - bool uses_report_ids[3]; // input, ouptput, feature - uint16_t input_report_size; - uint16_t output_report_size; - uint16_t feature_report_size; - WCHAR string[3][MAX_USB_STRING_LENGTH]; - uint8_t string_index[3]; // man, prod, ser -}; - typedef struct libusb_device_descriptor USB_DEVICE_DESCRIPTOR, *PUSB_DEVICE_DESCRIPTOR; struct windows_device_priv { uint8_t depth; // distance to HCD @@ -221,7 +154,6 @@ struct windows_device_priv { bool restricted_functionality; // indicates if the interface functionality is restricted // by Windows (eg. HID keyboards or mice cannot do R/W) } usb_interface[USB_MAXINTERFACES]; - struct hid_device_priv *hid; USB_DEVICE_DESCRIPTOR dev_descriptor; unsigned char **config_descriptor; // list of pointers to the cached config descriptors }; @@ -239,7 +171,6 @@ static inline void windows_device_priv_init(libusb_device* dev) { p->path = NULL; p->apib = &usb_api_backend[USB_API_UNSUPPORTED]; p->sub_api = SUB_API_NOTSET; - p->hid = NULL; p->active_config = 0; p->config_descriptor = NULL; memset(&(p->dev_descriptor), 0, sizeof(USB_DEVICE_DESCRIPTOR)); @@ -262,7 +193,6 @@ static inline void windows_device_priv_release(libusb_device* dev) { safe_free(p->config_descriptor[i]); } safe_free(p->config_descriptor); - safe_free(p->hid); for (i=0; i<USB_MAXINTERFACES; i++) { safe_free(p->usb_interface[i].path); safe_free(p->usb_interface[i].endpoint); @@ -290,9 +220,6 @@ static inline struct windows_device_handle_priv *_device_handle_priv( struct windows_transfer_priv { struct winfd pollable_fd; uint8_t interface_number; - uint8_t *hid_buffer; // 1 byte extended data buffer, required for HID - uint8_t *hid_dest; // transfer buffer destination, required for HID - size_t hid_expected_size; }; // used to match a device driver (including filter drivers) against a supported API @@ -821,98 +748,4 @@ struct winusb_interface { WinUsb_SetPowerPolicy_t SetPowerPolicy; WinUsb_WritePipe_t WritePipe; WinUsb_ResetDevice_t ResetDevice; -}; - -/* hid.dll interface */ - -#define HIDP_STATUS_SUCCESS 0x110000 -typedef void* PHIDP_PREPARSED_DATA; - -#pragma pack(1) -typedef struct { - ULONG Size; - USHORT VendorID; - USHORT ProductID; - USHORT VersionNumber; -} HIDD_ATTRIBUTES, *PHIDD_ATTRIBUTES; -#pragma pack() - -typedef USHORT USAGE; -typedef struct { - USAGE Usage; - USAGE UsagePage; - USHORT InputReportByteLength; - USHORT OutputReportByteLength; - USHORT FeatureReportByteLength; - USHORT Reserved[17]; - USHORT NumberLinkCollectionNodes; - USHORT NumberInputButtonCaps; - USHORT NumberInputValueCaps; - USHORT NumberInputDataIndices; - USHORT NumberOutputButtonCaps; - USHORT NumberOutputValueCaps; - USHORT NumberOutputDataIndices; - USHORT NumberFeatureButtonCaps; - USHORT NumberFeatureValueCaps; - USHORT NumberFeatureDataIndices; -} HIDP_CAPS, *PHIDP_CAPS; - -typedef enum _HIDP_REPORT_TYPE { - HidP_Input, - HidP_Output, - HidP_Feature -} HIDP_REPORT_TYPE; - -typedef struct _HIDP_VALUE_CAPS { - USAGE UsagePage; - UCHAR ReportID; - BOOLEAN IsAlias; - USHORT BitField; - USHORT LinkCollection; - USAGE LinkUsage; - USAGE LinkUsagePage; - BOOLEAN IsRange; - BOOLEAN IsStringRange; - BOOLEAN IsDesignatorRange; - BOOLEAN IsAbsolute; - BOOLEAN HasNull; - UCHAR Reserved; - USHORT BitSize; - USHORT ReportCount; - USHORT Reserved2[5]; - ULONG UnitsExp; - ULONG Units; - LONG LogicalMin, LogicalMax; - LONG PhysicalMin, PhysicalMax; - union { - struct { - USAGE UsageMin, UsageMax; - USHORT StringMin, StringMax; - USHORT DesignatorMin, DesignatorMax; - USHORT DataIndexMin, DataIndexMax; - } Range; - struct { - USAGE Usage, Reserved1; - USHORT StringIndex, Reserved2; - USHORT DesignatorIndex, Reserved3; - USHORT DataIndex, Reserved4; - } NotRange; - } u; -} HIDP_VALUE_CAPS, *PHIDP_VALUE_CAPS; - -DLL_DECLARE(WINAPI, BOOL, HidD_GetAttributes, (HANDLE, PHIDD_ATTRIBUTES)); -DLL_DECLARE(WINAPI, VOID, HidD_GetHidGuid, (LPGUID)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetPreparsedData, (HANDLE, PHIDP_PREPARSED_DATA *)); -DLL_DECLARE(WINAPI, BOOL, HidD_FreePreparsedData, (PHIDP_PREPARSED_DATA)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetManufacturerString, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetProductString, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetSerialNumberString, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, LONG, HidP_GetCaps, (PHIDP_PREPARSED_DATA, PHIDP_CAPS)); -DLL_DECLARE(WINAPI, BOOL, HidD_SetNumInputBuffers, (HANDLE, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_SetFeature, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetFeature, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetPhysicalDescriptor, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_GetInputReport, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_SetOutputReport, (HANDLE, PVOID, ULONG)); -DLL_DECLARE(WINAPI, BOOL, HidD_FlushQueue, (HANDLE)); -DLL_DECLARE(WINAPI, BOOL, HidP_GetValueCaps, (HIDP_REPORT_TYPE, PHIDP_VALUE_CAPS, PULONG, PHIDP_PREPARSED_DATA)); +};
\ No newline at end of file diff --git a/chromium/third_party/libxml/README.chromium b/chromium/third_party/libxml/README.chromium index 9305528022a..8ba967d176d 100644 --- a/chromium/third_party/libxml/README.chromium +++ b/chromium/third_party/libxml/README.chromium @@ -1,6 +1,6 @@ Name: libxml URL: http://xmlsoft.org -Version: 707ad080e61014ab4a6d60dc12875e233c1f673c +Version: 2677fbf4a4a6dec69ff52265addab713fe48ad1f License: MIT License File: src/Copyright Security Critical: yes diff --git a/chromium/third_party/libxml/chromium/chromium-issue-628581.patch b/chromium/third_party/libxml/chromium/chromium-issue-628581.patch index fb5d2a4fa47..42b7c630c96 100644 --- a/chromium/third_party/libxml/chromium/chromium-issue-628581.patch +++ b/chromium/third_party/libxml/chromium/chromium-issue-628581.patch @@ -71,7 +71,7 @@ index 53a6b7f0c961..e3136123dca6 100644 unsigned long oldnbent = ctxt->nbentities; xmlChar *rep; -+ ent->guard = XML_ENTITY_BEING_CHECKED; ++ ent->guard = XML_ENTITY_BEING_CHECKED; ent->checked = 1; ++ctxt->depth; @@ -79,10 +79,10 @@ index 53a6b7f0c961..e3136123dca6 100644 XML_SUBSTITUTE_REF, 0, 0, 0); --ctxt->depth; + ent->guard = XML_ENTITY_NOT_BEING_CHECKED; - if ((rep == NULL) || (ctxt->errNo == XML_ERR_ENTITY_LOOP)) { + if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { ent->content[0] = 0; } -@@ -7105,23 +7111,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { +@@ -7329,23 +7335,28 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { * if its replacement text matches the production labeled * content. */ @@ -128,7 +128,7 @@ index 53a6b7f0c961..e3136123dca6 100644 /* * Store the number of entities needing parsing for this entity -@@ -7229,23 +7240,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { +@@ -7448,23 +7459,29 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { else user_data = ctxt->userData; diff --git a/chromium/third_party/libxml/linux/xml2-config b/chromium/third_party/libxml/linux/xml2-config index bb834c64d8d..6ed8eb144eb 100755 --- a/chromium/third_party/libxml/linux/xml2-config +++ b/chromium/third_party/libxml/linux/xml2-config @@ -86,12 +86,12 @@ while test $# -gt 0; do then if [ "-L${libdir}" = "-L/usr/lib" -o "-L${libdir}" = "-L/usr/lib64" ] then - echo -lxml2 -licui18n -licuuc -licudata -lm + echo -lxml2 -L/usr/lib/x86_64-linux-gnu -licui18n -licuuc -licudata -lm else - echo -L${libdir} -lxml2 -licui18n -licuuc -licudata -lm + echo -L${libdir} -lxml2 -L/usr/lib/x86_64-linux-gnu -licui18n -licuuc -licudata -lm fi else - echo -L${libdir} -lxml2 -licui18n -licuuc -licudata -lm + echo -L${libdir} -lxml2 -L/usr/lib/x86_64-linux-gnu -licui18n -licuuc -licudata -lm fi ;; diff --git a/chromium/third_party/libxml/src/HTMLparser.c b/chromium/third_party/libxml/src/HTMLparser.c index 9adeb1748d9..7e243e600f8 100644 --- a/chromium/third_party/libxml/src/HTMLparser.c +++ b/chromium/third_party/libxml/src/HTMLparser.c @@ -3635,7 +3635,7 @@ htmlCheckEncodingDirect(htmlParserCtxtPtr ctxt, const xmlChar *encoding) { */ processed = ctxt->input->cur - ctxt->input->base; xmlBufShrink(ctxt->input->buf->buffer, processed); - nbchars = xmlCharEncInput(ctxt->input->buf, 0); + nbchars = xmlCharEncInput(ctxt->input->buf, 1); if (nbchars < 0) { htmlParseErr(ctxt, XML_ERR_INVALID_ENCODING, "htmlCheckEncoding: encoder error\n", diff --git a/chromium/third_party/libxml/src/configure.ac b/chromium/third_party/libxml/src/configure.ac index ebfa70221d1..988e32e553d 100644 --- a/chromium/third_party/libxml/src/configure.ac +++ b/chromium/third_party/libxml/src/configure.ac @@ -769,9 +769,9 @@ else fi # warnings we'd like to see - EXTRA_CFLAGS="${EXTRA_CFLAGS} -pedantic -Wall -Wextra -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" + EXTRA_CFLAGS="${EXTRA_CFLAGS} -pedantic -W -Wformat -Wno-format-extra-args -Wunused -Wimplicit -Wreturn-type -Wswitch -Wcomment -Wtrigraphs -Wchar-subscripts -Wuninitialized -Wparentheses -Wshadow -Wpointer-arith -Wcast-align -Wwrite-strings -Waggregate-return -Wstrict-prototypes -Wmissing-prototypes -Wnested-externs -Winline -Wredundant-decls" # warnings we'd like to supress - EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-long-long -Wno-format-extra-args -Wno-array-bounds" + EXTRA_CFLAGS="${EXTRA_CFLAGS} -Wno-long-long" case "${host}" in alpha*-*-linux* ) EXTRA_CFLAGS="${EXTRA_CFLAGS} -mieee" diff --git a/chromium/third_party/libxml/src/libxml2.spec b/chromium/third_party/libxml/src/libxml2.spec index 2b46112a633..e0d24ffe28d 100644 --- a/chromium/third_party/libxml/src/libxml2.spec +++ b/chromium/third_party/libxml/src/libxml2.spec @@ -203,6 +203,6 @@ rm -fr %{buildroot} %endif # with_python3 %changelog -* Tue Jan 30 2018 Daniel Veillard <veillard@redhat.com> +* Wed Dec 13 2017 Daniel Veillard <veillard@redhat.com> - upstream release 2.9.7 see http://xmlsoft.org/news.html diff --git a/chromium/third_party/libxml/src/parser.c b/chromium/third_party/libxml/src/parser.c index 072b1293ea5..6a34b270648 100644 --- a/chromium/third_party/libxml/src/parser.c +++ b/chromium/third_party/libxml/src/parser.c @@ -147,7 +147,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, unsigned long oldnbent = ctxt->nbentities; xmlChar *rep; - ent->guard = XML_ENTITY_BEING_CHECKED; + ent->guard = XML_ENTITY_BEING_CHECKED; ent->checked = 1; ++ctxt->depth; @@ -155,7 +155,7 @@ xmlParserEntityCheck(xmlParserCtxtPtr ctxt, size_t size, XML_SUBSTITUTE_REF, 0, 0, 0); --ctxt->depth; ent->guard = XML_ENTITY_NOT_BEING_CHECKED; - if ((rep == NULL) || (ctxt->errNo == XML_ERR_ENTITY_LOOP)) { + if (ctxt->errNo == XML_ERR_ENTITY_LOOP) { ent->content[0] = 0; } @@ -3376,9 +3376,9 @@ xmlParseNCNameComplex(xmlParserCtxtPtr ctxt) { */ ctxt->input->cur -= l; GROW; + ctxt->input->cur += l; if (ctxt->instate == XML_PARSER_EOF) return(NULL); - ctxt->input->cur += l; c = CUR_CHAR(l); } } @@ -7200,8 +7200,6 @@ xmlParseReference(xmlParserCtxtPtr ctxt) { (ret != XML_WAR_UNDECLARED_ENTITY)) { xmlFatalErrMsgStr(ctxt, XML_ERR_UNDECLARED_ENTITY, "Entity '%s' failed to parse\n", ent->name); - if (ent->content != NULL) - ent->content[0] = 0; xmlParserEntityCheck(ctxt, 0, ent, 0); } else if (list != NULL) { xmlFreeNodeList(list); @@ -12235,7 +12233,6 @@ xmldecl_done: /* TODO 2.6.0 */ xmlGenericError(xmlGenericErrorContext, "xmlParseChunk: encoder error\n"); - xmlHaltParser(ctxt); return(XML_ERR_INVALID_ENCODING); } xmlBufSetInputBaseCur(in->buffer, ctxt->input, base, current); @@ -13384,7 +13381,6 @@ xmlParseBalancedChunkMemoryInternal(xmlParserCtxtPtr oldctxt, ctxt->userData = ctxt; if (ctxt->dict != NULL) xmlDictFree(ctxt->dict); ctxt->dict = oldctxt->dict; - ctxt->input_id = oldctxt->input_id + 1; ctxt->str_xml = xmlDictLookup(ctxt->dict, BAD_CAST "xml", 3); ctxt->str_xmlns = xmlDictLookup(ctxt->dict, BAD_CAST "xmlns", 5); ctxt->str_xml_ns = xmlDictLookup(ctxt->dict, XML_XML_NAMESPACE, 36); @@ -13638,7 +13634,6 @@ xmlParseInNodeContext(xmlNodePtr node, const char *data, int datalen, xmlDetectSAX2(ctxt); ctxt->myDoc = doc; /* parsing in context, i.e. as within existing content */ - ctxt->input_id = 2; ctxt->instate = XML_PARSER_CONTENT; fake = xmlNewComment(NULL); @@ -13851,7 +13846,6 @@ xmlParseBalancedChunkMemoryRecover(xmlDocPtr doc, xmlSAXHandlerPtr sax, newDoc->oldNs = doc->oldNs; } ctxt->instate = XML_PARSER_CONTENT; - ctxt->input_id = 2; ctxt->depth = depth; /* @@ -14012,11 +14006,6 @@ xmlCreateEntityParserCtxtInternal(const xmlChar *URL, const xmlChar *ID, if (pctx != NULL) { ctxt->options = pctx->options; ctxt->_private = pctx->_private; - /* - * this is a subparser of pctx, so the input_id should be - * incremented to distinguish from main entity - */ - ctxt->input_id = pctx->input_id + 1; } uri = xmlBuildURI(URL, base); diff --git a/chromium/third_party/libxml/src/parserInternals.c b/chromium/third_party/libxml/src/parserInternals.c index cfeb0a2ed60..9d45e5caa15 100644 --- a/chromium/third_party/libxml/src/parserInternals.c +++ b/chromium/third_party/libxml/src/parserInternals.c @@ -1214,7 +1214,7 @@ xmlSwitchInputEncodingInt(xmlParserCtxtPtr ctxt, xmlParserInputPtr input, /* * convert as much as possible of the buffer */ - nbchars = xmlCharEncInput(input->buf, 0); + nbchars = xmlCharEncInput(input->buf, 1); } else { /* * convert just enough to get diff --git a/chromium/third_party/libxml/src/win32/Makefile.msvc b/chromium/third_party/libxml/src/win32/Makefile.msvc index 491dc880128..ff8378e29a9 100644 --- a/chromium/third_party/libxml/src/win32/Makefile.msvc +++ b/chromium/third_party/libxml/src/win32/Makefile.msvc @@ -22,7 +22,6 @@ AUTOCONF = .\config.msvc XML_NAME = xml2 XML_BASENAME = lib$(XML_NAME) XML_SO = $(XML_BASENAME).dll -XML_RES = $(XML_BASENAME).res XML_IMP = $(XML_BASENAME).lib XML_DEF = $(XML_BASENAME).def XML_A = $(XML_BASENAME)_a.lib @@ -70,11 +69,7 @@ LIBS = $(LIBS) wsock32.lib ws2_32.lib LIBS = $(LIBS) iconv.lib !endif !if "$(WITH_ICU)" == "1" -!if "$(STATIC)" == "1" -LIBS = $(LIBS) advapi32.lib sicuuc.lib sicuin.lib sicudt.lib -!else -LIBS = $(LIBS) icuuc.lib icuin.lib icudt.lib -!endif +LIBS = $(LIBS) icu.lib !endif !if "$(WITH_ZLIB)" == "1" # could be named differently zdll or zlib @@ -261,10 +256,7 @@ UTILS = $(BINDIR)\xmllint.exe\ $(BINDIR)\testXPath.exe\ $(BINDIR)\runtest.exe\ $(BINDIR)\runsuite.exe\ - $(BINDIR)\runxmlconf.exe\ $(BINDIR)\testapi.exe\ - $(BINDIR)\testchar.exe\ - $(BINDIR)\testdict.exe\ $(BINDIR)\testlimits.exe\ $(BINDIR)\testrecurse.exe @@ -375,13 +367,11 @@ $(XML_OBJS_A_DLL) : $(XML_INTDIR_A_DLL) # Creates the export definition file (DEF) for libxml. $(XML_INTDIR)\$(XML_DEF) : $(XML_INTDIR) $(XML_DEF).src $(CPP) $(CPPFLAGS) $(XML_DEF).src > $(XML_INTDIR)\$(XML_DEF) -$(XML_INTDIR)\$(XML_RES) : $(XML_INTDIR) libxml2.rc - rc -Fo $(XML_INTDIR)\$(XML_RES) libxml2.rc # Creates the libxml shared object. -$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF) $(XML_INTDIR)\$(XML_RES) +$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF) $(LD) $(LDFLAGS) /DLL \ - /IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(XML_INTDIR)\$(XML_RES) $(LIBS) + /IMPLIB:$(BINDIR)\$(XML_IMP) /OUT:$(BINDIR)\$(XML_SO) $(XML_OBJS) $(LIBS) @$(_VC_MANIFEST_EMBED_DLL) #$(BINDIR)\$(XML_SO) : $(BINDIR) $(XML_OBJS) $(XML_INTDIR)\$(XML_DEF) diff --git a/chromium/third_party/libxml/src/win32/configure.js b/chromium/third_party/libxml/src/win32/configure.js index dbf238c70c4..92b9ba052c2 100644 --- a/chromium/third_party/libxml/src/win32/configure.js +++ b/chromium/third_party/libxml/src/win32/configure.js @@ -280,18 +280,6 @@ function discoverVersion() vf.WriteLine("DYNRUNTIME=" + (dynruntime? "1" : "0")); } vf.Close(); - versionFile = "rcVersion.h" - vf = fso.CreateTextFile(versionFile, true); - vf.WriteLine("/*"); - vf.WriteLine(" " + versionFile); - vf.WriteLine(" This file is generated automatically by " + WScript.ScriptName + "."); - vf.WriteLine("*/"); - vf.WriteBlankLines(1); - vf.WriteLine("#define LIBXML_MAJOR_VERSION " + verMajor); - vf.WriteLine("#define LIBXML_MINOR_VERSION " + verMinor); - vf.WriteLine("#define LIBXML_MICRO_VERSION " + verMicro); - vf.WriteLine("#define LIBXML_DOTTED_VERSION " + "\"" + verMajor + "." + verMinor + "." + verMicro + "\""); - vf.Close() } /* Configures libxml. This one will generate xmlversion.h from xmlversion.h.in diff --git a/chromium/third_party/libxml/src/win32/libxml2.rc b/chromium/third_party/libxml/src/win32/libxml2.rc deleted file mode 100644 index c774a5ee5a9..00000000000 --- a/chromium/third_party/libxml/src/win32/libxml2.rc +++ /dev/null @@ -1,36 +0,0 @@ -#include <winver.h> -#include "rcVersion.h" - -VS_VERSION_INFO VERSIONINFO - FILEVERSION LIBXML_MAJOR_VERSION,LIBXML_MINOR_VERSION,LIBXML_MICRO_VERSION,0 - PRODUCTVERSION LIBXML_MAJOR_VERSION,LIBXML_MINOR_VERSION,LIBXML_MICRO_VERSION,0 - FILEFLAGSMASK VS_FFI_FILEFLAGSMASK -#ifdef _DEBUG - FILEFLAGS VS_FF_DEBUG -#else - FILEFLAGS 0 -#endif - FILEOS VOS__WINDOWS32 - FILETYPE VFT_DLL - FILESUBTYPE VFT2_UNKNOWN // not used -BEGIN - BLOCK "StringFileInfo" - BEGIN - BLOCK "04090000" /* Lang = US English, Charset = ASCII */ - BEGIN - VALUE "FileDescription", "libxml2 library\0" - VALUE "FileVersion", LIBXML_DOTTED_VERSION "\0" - VALUE "InternalName", "libxml2.dll\0" - VALUE "LegalCopyright", "Copyright (C) Daniel Veillard\0" - VALUE "LegalTrademarks", "\0" - VALUE "OriginalFilename", "libxml2.dll\0" - VALUE "ProductName", "libxml2\0" - VALUE "ProductVersion", LIBXML_DOTTED_VERSION "\0" - VALUE "Comments", "For more information visit http://xmlsoft.org/\0" - END - END - BLOCK "VarFileInfo" - BEGIN - VALUE "Translation", 0x0409, 0 /* US English, ASCII */ - END -END diff --git a/chromium/third_party/libxml/src/xmlIO.c b/chromium/third_party/libxml/src/xmlIO.c index 8254347708f..f61dd05a905 100644 --- a/chromium/third_party/libxml/src/xmlIO.c +++ b/chromium/third_party/libxml/src/xmlIO.c @@ -3157,7 +3157,7 @@ xmlParserInputBufferPush(xmlParserInputBufferPtr in, * convert as much as possible to the parser reading buffer. */ use = xmlBufUse(in->raw); - nbchars = xmlCharEncInput(in, 0); + nbchars = xmlCharEncInput(in, 1); if (nbchars < 0) { xmlIOErr(XML_IO_ENCODER, NULL); in->error = XML_IO_ENCODER; @@ -3273,7 +3273,7 @@ xmlParserInputBufferGrow(xmlParserInputBufferPtr in, int len) { * convert as much as possible to the parser reading buffer. */ use = xmlBufUse(in->raw); - nbchars = xmlCharEncInput(in, 0); + nbchars = xmlCharEncInput(in, 1); if (nbchars < 0) { xmlIOErr(XML_IO_ENCODER, NULL); in->error = XML_IO_ENCODER; diff --git a/chromium/third_party/pdfium/core/fxcrt/widestring.cpp b/chromium/third_party/pdfium/core/fxcrt/widestring.cpp index 8d47564e13f..7b5bf66fd38 100644 --- a/chromium/third_party/pdfium/core/fxcrt/widestring.cpp +++ b/chromium/third_party/pdfium/core/fxcrt/widestring.cpp @@ -924,7 +924,7 @@ int WideString::Compare(const WideString& str) const { return result; if (this_len == that_len) return 0; - return this_len < that_len; + return this_len < that_len ? -1 : 1; } int WideString::CompareNoCase(const wchar_t* lpsz) const { diff --git a/chromium/third_party/pdfium/core/fxcrt/widestring_unittest.cpp b/chromium/third_party/pdfium/core/fxcrt/widestring_unittest.cpp index 2fb9e8c8b41..473d59c4911 100644 --- a/chromium/third_party/pdfium/core/fxcrt/widestring_unittest.cpp +++ b/chromium/third_party/pdfium/core/fxcrt/widestring_unittest.cpp @@ -52,15 +52,18 @@ TEST(WideString, ElementAccess) { TEST(WideString, OperatorLT) { WideString empty; WideString a(L"a"); + WideString ab(L"ab"); WideString abc(L"\x0110qq"); // Comes before despite endianness. WideString def(L"\x1001qq"); // Comes after despite endianness. WideStringView v_empty; WideStringView v_a(L"a"); + WideStringView v_ab(L"ab"); WideStringView v_abc(L"\x0110qq"); WideStringView v_def(L"\x1001qq"); const wchar_t* const c_null = nullptr; const wchar_t* const c_empty = L""; const wchar_t* const c_a = L"a"; + const wchar_t* const c_ab = L"ab"; const wchar_t* const c_abc = L"\x0110qq"; const wchar_t* const c_def = L"\x1001qq"; @@ -142,6 +145,14 @@ TEST(WideString, OperatorLT) { EXPECT_FALSE(def < c_abc); EXPECT_TRUE(abc < v_def); EXPECT_FALSE(def < v_abc); + + EXPECT_TRUE(a < ab); + EXPECT_TRUE(a < c_ab); + EXPECT_TRUE(a < v_ab); + EXPECT_TRUE(c_a < ab); + EXPECT_TRUE(c_a < v_ab); + EXPECT_TRUE(v_a < c_ab); + EXPECT_TRUE(v_a < v_ab); } TEST(WideString, OperatorEQ) { diff --git a/chromium/third_party/skia/gm/gradients_2pt_conical.cpp b/chromium/third_party/skia/gm/gradients_2pt_conical.cpp index 8a6b19a8f25..f2e2d1810e0 100644 --- a/chromium/third_party/skia/gm/gradients_2pt_conical.cpp +++ b/chromium/third_party/skia/gm/gradients_2pt_conical.cpp @@ -98,17 +98,26 @@ static sk_sp<SkShader> Make2ConicalInsideFlip(const SkPoint pts[2], const GradDa static sk_sp<SkShader> Make2ConicalInsideCenter(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm, const SkMatrix& localMatrix) { - SkPoint center0, center1; + SkPoint center0; center0.set(SkScalarAve(pts[0].fX, pts[1].fX), SkScalarAve(pts[0].fY, pts[1].fY)); - center1.set(SkScalarInterp(pts[0].fX, pts[1].fX, SkIntToScalar(3)/5), - SkScalarInterp(pts[0].fY, pts[1].fY, SkIntToScalar(1)/4)); return SkGradientShader::MakeTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 7, center0, (pts[1].fX - pts[0].fX) / 2, data.fColors, data.fPos, data.fCount, tm, 0, &localMatrix); } +static sk_sp<SkShader> Make2ConicalInsideCenterReversed(const SkPoint pts[2], const GradData& data, + SkShader::TileMode tm, const SkMatrix& localMatrix) { + SkPoint center0; + center0.set(SkScalarAve(pts[0].fX, pts[1].fX), + SkScalarAve(pts[0].fY, pts[1].fY)); + return SkGradientShader::MakeTwoPointConical(center0, (pts[1].fX - pts[0].fX) / 2, + center0, (pts[1].fX - pts[0].fX) / 7, + data.fColors, data.fPos, data.fCount, tm, + 0, &localMatrix); +} + static sk_sp<SkShader> Make2ConicalZeroRad(const SkPoint pts[2], const GradData& data, SkShader::TileMode tm, const SkMatrix& localMatrix) { SkPoint center0, center1; @@ -270,6 +279,7 @@ constexpr GradMaker gGradMakersOutside[] = { constexpr GradMaker gGradMakersInside[] = { Make2ConicalInside, Make2ConicalInsideFlip, Make2ConicalInsideCenter, Make2ConicalZeroRad, Make2ConicalZeroRadFlip, Make2ConicalZeroRadCenter, + Make2ConicalInsideCenterReversed }; constexpr GradMaker gGradMakersEdgeCases[] = { diff --git a/chromium/third_party/skia/src/core/SkPixmap.cpp b/chromium/third_party/skia/src/core/SkPixmap.cpp index 7873a9b8ce6..ca86c7b2b91 100644 --- a/chromium/third_party/skia/src/core/SkPixmap.cpp +++ b/chromium/third_party/skia/src/core/SkPixmap.cpp @@ -121,7 +121,7 @@ bool SkPixmap::erase(SkColor color, const SkIRect& inArea) const { && width == this->rowBytesAsPixels() && inArea == this->bounds()) { // All formats represent SkColor(0) as byte 0. - memset(this->writable_addr(), 0, height * rowBytes); + memset(this->writable_addr(), 0, (int64_t)height * rowBytes); return true; } diff --git a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp index 38e4495c840..6956fa22aa3 100644 --- a/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp +++ b/chromium/third_party/skia/src/shaders/gradients/SkTwoPointConicalGradient_gpu.cpp @@ -92,7 +92,9 @@ public: bool isNativelyFocal() const { return this->isFocal() && fData.fFocalData.isNativelyFocal(); } // Note that focalX = f = r0 / (r0 - r1), so 1 - focalX > 0 == r0 < r1 - bool isRadiusIncreasing() const { return this->isFocal() && 1 - fData.fFocalData.fFocalX > 0; } + bool isRadiusIncreasing() const { + return this->isFocal() ? 1 - fData.fFocalData.fFocalX > 0 : this->diffRadius() > 0; + } protected: void onGetGLSLProcessorKey(const GrShaderCaps& c, GrProcessorKeyBuilder* b) const override { @@ -237,7 +239,8 @@ protected: const char* p = coords2D.c_str(); if (effect.getType() == Type::kRadial) { - fragBuilder->codeAppendf("half %s = length(%s) - %s;", tName, p, p0.c_str()); + char sign = effect.diffRadius() < 0 ? '-' : '+'; + fragBuilder->codeAppendf("half %s = %clength(%s) - %s;", tName, sign, p, p0.c_str()); } else { // output will default to transparent black (we simply won't write anything // else to it if invalid, instead of discarding or returning prematurely) @@ -263,8 +266,9 @@ protected: void onSetData(const GrGLSLProgramDataManager& pdman, const GrFragmentProcessor& p) override { INHERITED::onSetData(pdman, p); const TwoPointConicalEffect& effect = p.cast<TwoPointConicalEffect>(); - // kRadialType should imply r1 - r0 = 1 (after our transformation) so r0 = r0 / (r1 - r0) - SkASSERT(effect.getType() == Type::kStrip || SkScalarNearlyZero(effect.diffRadius() - 1)); + // kRadialType should imply |r1 - r0| = 1 (after our transformation) + SkASSERT(effect.getType() == Type::kStrip || + SkScalarNearlyZero(SkTAbs(effect.diffRadius()) - 1)); pdman.set1f(fParamUni, effect.getType() == Type::kRadial ? effect.r0() : effect.r0() * effect.r0()); } @@ -407,12 +411,14 @@ std::unique_ptr<GrFragmentProcessor> Gr2PtConicalGradientEffect::Make( TwoPointConicalEffect::Data::Data(const SkTwoPointConicalGradient& shader, SkMatrix& matrix) { fType = shader.getType(); if (fType == Type::kRadial) { - SkScalar dr = shader.getDiffRadius(); - // Map center to (0, 0) and scale dr to 1 + // Map center to (0, 0) matrix.postTranslate(-shader.getStartCenter().fX, -shader.getStartCenter().fY); + + // scale |fDiffRadius| to 1 + SkScalar dr = shader.getDiffRadius(); matrix.postScale(1 / dr, 1 / dr); fRadius0 = shader.getStartRadius() / dr; - fDiffRadius = 1; + fDiffRadius = dr < 0 ? -1 : 1; } else if (fType == Type::kStrip) { fRadius0 = shader.getStartRadius() / shader.getCenterX1(); fDiffRadius = 0; diff --git a/chromium/third_party/webrtc/media/engine/webrtcvoiceengine.cc b/chromium/third_party/webrtc/media/engine/webrtcvoiceengine.cc index a1cbf9204f3..5e62d3dbacb 100644 --- a/chromium/third_party/webrtc/media/engine/webrtcvoiceengine.cc +++ b/chromium/third_party/webrtc/media/engine/webrtcvoiceengine.cc @@ -1198,8 +1198,10 @@ class WebRtcVoiceMediaChannel::WebRtcAudioReceiveStream { void SetRawAudioSink(std::unique_ptr<webrtc::AudioSinkInterface> sink) { RTC_DCHECK(worker_thread_checker_.CalledOnValidThread()); + // Need to update the stream's sink first; once raw_audio_sink_ is + // reassigned, whatever was in there before is destroyed. + stream_->SetSink(sink.get()); raw_audio_sink_ = std::move(sink); - stream_->SetSink(raw_audio_sink_.get()); } void SetOutputVolume(double volume) { diff --git a/chromium/tools/metrics/histograms/enums.xml b/chromium/tools/metrics/histograms/enums.xml index 0f26a770d28..55339d65908 100644 --- a/chromium/tools/metrics/histograms/enums.xml +++ b/chromium/tools/metrics/histograms/enums.xml @@ -18609,6 +18609,12 @@ Called by update_net_error_codes.py.--> <int value="6" label="Media View"/> </enum> +<enum name="FileManagerZipHandlerType"> + <int value="0" label="ZIP unpacker"/> + <int value="1" label="Zip Archiver (open)"/> + <int value="2" label="Zip Archiver (pack)"/> +</enum> + <enum name="FileMetricsProviderAccessResult"> <int value="0" label="File was mapped."/> <int value="1" label="File doesn't exist."/> @@ -18742,6 +18748,7 @@ Called by update_net_error_codes.py.--> <int value="3" label="Have SSO account, Skipped Immediately"/> <int value="4" label="Have SSO account, Successful"/> <int value="5" label="Have SSO account, Gave Up"/> + <int value="6" label="Could not create FirstRun Sentinel"/> </enum> <enum name="FirstUserActionType"> diff --git a/chromium/tools/metrics/histograms/histograms.xml b/chromium/tools/metrics/histograms/histograms.xml index b4ec73078f6..597f164423f 100644 --- a/chromium/tools/metrics/histograms/histograms.xml +++ b/chromium/tools/metrics/histograms/histograms.xml @@ -26279,6 +26279,14 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries. </summary> </histogram> +<histogram name="FileBrowser.ZipFileTask" enum="FileManagerZipHandlerType"> + <owner>yamaguchi@chromium.org</owner> + <summary> + Chrome OS File Browser: counts the number of times ZIP file was opened or + created, categorized by component extensions and its operation types. + </summary> +</histogram> + <histogram name="FileReaderSync.WorkerType" enum="FileReaderSyncWorkerType"> <owner>mek@chromium.org</owner> <summary> diff --git a/chromium/ui/base/clipboard/clipboard_win.cc b/chromium/ui/base/clipboard/clipboard_win.cc index 3757fd10986..e49dd8c8127 100644 --- a/chromium/ui/base/clipboard/clipboard_win.cc +++ b/chromium/ui/base/clipboard/clipboard_win.cc @@ -208,12 +208,13 @@ void FreeData(unsigned int format, HANDLE data) { } template <typename StringType> -void TrimTrailingNulls(StringType* result) { - // Text copied to the clipboard may explicitly contain trailing null - // characters that should be ignored, depending on the application that does - // the copying. - while (!result->empty() && result->back() == 0) - result->pop_back(); +void TrimAfterNull(StringType* result) { + // Text copied to the clipboard may explicitly contain null characters that + // should be ignored, depending on the application that does the copying. + constexpr typename StringType::value_type kNull = 0; + size_t pos = result->find_first_of(kNull); + if (pos != StringType::npos) + result->resize(pos); } } // namespace @@ -505,7 +506,7 @@ void ClipboardWin::ReadText(ClipboardType type, base::string16* result) const { result->assign(static_cast<const base::char16*>(::GlobalLock(data)), ::GlobalSize(data) / sizeof(base::char16)); ::GlobalUnlock(data); - TrimTrailingNulls(result); + TrimAfterNull(result); } void ClipboardWin::ReadAsciiText(ClipboardType type, @@ -530,7 +531,7 @@ void ClipboardWin::ReadAsciiText(ClipboardType type, result->assign(static_cast<const char*>(::GlobalLock(data)), ::GlobalSize(data)); ::GlobalUnlock(data); - TrimTrailingNulls(result); + TrimAfterNull(result); } void ClipboardWin::ReadHTML(ClipboardType type, @@ -560,7 +561,7 @@ void ClipboardWin::ReadHTML(ClipboardType type, std::string cf_html(static_cast<const char*>(::GlobalLock(data)), ::GlobalSize(data)); ::GlobalUnlock(data); - TrimTrailingNulls(&cf_html); + TrimAfterNull(&cf_html); size_t html_start = std::string::npos; size_t start_index = std::string::npos; @@ -593,7 +594,7 @@ void ClipboardWin::ReadRTF(ClipboardType type, std::string* result) const { DCHECK_EQ(type, CLIPBOARD_TYPE_COPY_PASTE); ReadData(GetRtfFormatType(), result); - TrimTrailingNulls(result); + TrimAfterNull(result); } SkBitmap ClipboardWin::ReadImage(ClipboardType type) const { @@ -716,7 +717,7 @@ void ClipboardWin::ReadBookmark(base::string16* title, std::string* url) const { base::string16 bookmark(static_cast<const base::char16*>(::GlobalLock(data)), ::GlobalSize(data) / sizeof(base::char16)); ::GlobalUnlock(data); - TrimTrailingNulls(&bookmark); + TrimAfterNull(&bookmark); ParseBookmarkClipboardFormat(bookmark, title, url); } diff --git a/chromium/v8/AUTHORS b/chromium/v8/AUTHORS index b2b01df8882..dfd3eef878c 100644 --- a/chromium/v8/AUTHORS +++ b/chromium/v8/AUTHORS @@ -136,7 +136,6 @@ Sanjoy Das <sanjoy@playingwithpointers.com> Seo Sanghyeon <sanxiyn@gmail.com> Stefan Penner <stefan.penner@gmail.com> Sylvestre Ledru <sledru@mozilla.com> -Taketoshi Aono <brn@b6n.ch> Tiancheng "Timothy" Gu <timothygu99@gmail.com> Tobias Burnus <burnus@net-b.de> Victor Costan <costan@gmail.com> diff --git a/chromium/v8/include/v8-version.h b/chromium/v8/include/v8-version.h index 6cc98294ec5..71f3b774a33 100644 --- a/chromium/v8/include/v8-version.h +++ b/chromium/v8/include/v8-version.h @@ -11,7 +11,7 @@ #define V8_MAJOR_VERSION 6 #define V8_MINOR_VERSION 5 #define V8_BUILD_NUMBER 254 -#define V8_PATCH_LEVEL 31 +#define V8_PATCH_LEVEL 43 // Use 1 for candidates and 0 otherwise. // (Boolean macro values are not supported by all preprocessors.) diff --git a/chromium/v8/src/bootstrapper.cc b/chromium/v8/src/bootstrapper.cc index 399b705f008..2bc833fe296 100644 --- a/chromium/v8/src/bootstrapper.cc +++ b/chromium/v8/src/bootstrapper.cc @@ -1508,9 +1508,9 @@ void Genesis::InitializeGlobal(Handle<JSGlobalObject> global_object, object_function, "keys", Builtins::kObjectKeys, 1, true); native_context()->set_object_keys(*object_keys); SimpleInstallFunction(object_function, factory->entries_string(), - Builtins::kObjectEntries, 1, true); + Builtins::kObjectEntries, 1, false); SimpleInstallFunction(object_function, factory->values_string(), - Builtins::kObjectValues, 1, true); + Builtins::kObjectValues, 1, false); SimpleInstallFunction(isolate->initial_object_prototype(), "__defineGetter__", Builtins::kObjectDefineGetter, 2, diff --git a/chromium/v8/src/builtins/builtins-definitions.h b/chromium/v8/src/builtins/builtins-definitions.h index 0ffd15df7c0..a4a0bb9e2cb 100644 --- a/chromium/v8/src/builtins/builtins-definitions.h +++ b/chromium/v8/src/builtins/builtins-definitions.h @@ -755,7 +755,7 @@ namespace internal { CPP(ObjectDefineProperties) \ CPP(ObjectDefineProperty) \ CPP(ObjectDefineSetter) \ - TFJ(ObjectEntries, 1, kObject) \ + CPP(ObjectEntries) \ CPP(ObjectFreeze) \ TFJ(ObjectGetOwnPropertyDescriptor, \ SharedFunctionInfo::kDontAdaptArgumentsSentinel) \ @@ -785,7 +785,7 @@ namespace internal { /* ES #sec-object.prototype.tolocalestring */ \ TFJ(ObjectPrototypeToLocaleString, 0) \ CPP(ObjectSeal) \ - TFJ(ObjectValues, 1, kObject) \ + CPP(ObjectValues) \ \ /* instanceof */ \ TFC(OrdinaryHasInstance, Compare, 1) \ diff --git a/chromium/v8/src/builtins/builtins-object-gen.cc b/chromium/v8/src/builtins/builtins-object-gen.cc index 9e344820dcc..4cd012e6f01 100644 --- a/chromium/v8/src/builtins/builtins-object-gen.cc +++ b/chromium/v8/src/builtins/builtins-object-gen.cc @@ -16,8 +16,6 @@ namespace internal { // ES6 section 19.1 Object Objects typedef compiler::Node Node; -template <class T> -using TNode = CodeStubAssembler::TNode<T>; class ObjectBuiltinsAssembler : public CodeStubAssembler { public: @@ -36,46 +34,6 @@ class ObjectBuiltinsAssembler : public CodeStubAssembler { Node* ConstructDataDescriptor(Node* context, Node* value, Node* writable, Node* enumerable, Node* configurable); Node* GetAccessorOrUndefined(Node* accessor, Label* if_bailout); - - Node* IsSpecialReceiverMap(SloppyTNode<Map> map); -}; - -class ObjectEntriesValuesBuiltinsAssembler : public ObjectBuiltinsAssembler { - public: - explicit ObjectEntriesValuesBuiltinsAssembler( - compiler::CodeAssemblerState* state) - : ObjectBuiltinsAssembler(state) {} - - protected: - enum CollectType { kEntries, kValues }; - - TNode<Word32T> IsStringWrapperElementsKind(TNode<Map> map); - - TNode<BoolT> IsPropertyEnumerable(TNode<Uint32T> details); - - TNode<BoolT> IsPropertyKindAccessor(TNode<Uint32T> kind); - - TNode<BoolT> IsPropertyKindData(TNode<Uint32T> kind); - - TNode<Uint32T> HasHiddenPrototype(TNode<Map> map); - - TNode<Uint32T> LoadPropertyKind(TNode<Uint32T> details) { - return DecodeWord32<PropertyDetails::KindField>(details); - } - - void GetOwnValuesOrEntries(TNode<Context> context, TNode<Object> maybe_object, - CollectType collect_type); - - void GotoIfMapHasSlowProperties(TNode<Map> map, Label* if_slow); - - TNode<JSArray> FastGetOwnValuesOrEntries( - TNode<Context> context, TNode<JSObject> object, - Label* if_call_runtime_with_fast_path, Label* if_no_properties, - CollectType collect_type); - - TNode<JSArray> FinalizeValuesOrEntriesJSArray( - TNode<Context> context, TNode<FixedArray> values_or_entries, - TNode<IntPtrT> size, TNode<Map> array_map, Label* if_empty); }; void ObjectBuiltinsAssembler::ReturnToStringFormat(Node* context, @@ -139,249 +97,6 @@ Node* ObjectBuiltinsAssembler::ConstructDataDescriptor(Node* context, return js_desc; } -Node* ObjectBuiltinsAssembler::IsSpecialReceiverMap(SloppyTNode<Map> map) { - CSA_SLOW_ASSERT(this, IsMap(map)); - Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); - uint32_t mask = - Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask; - USE(mask); - // Interceptors or access checks imply special receiver. - CSA_ASSERT(this, - SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, - Int32Constant(1), MachineRepresentation::kWord32)); - return is_special; -} - -TNode<Word32T> -ObjectEntriesValuesBuiltinsAssembler::IsStringWrapperElementsKind( - TNode<Map> map) { - Node* kind = LoadMapElementsKind(map); - return Word32Or( - Word32Equal(kind, Int32Constant(FAST_STRING_WRAPPER_ELEMENTS)), - Word32Equal(kind, Int32Constant(SLOW_STRING_WRAPPER_ELEMENTS))); -} - -TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyEnumerable( - TNode<Uint32T> details) { - TNode<Uint32T> attributes = - DecodeWord32<PropertyDetails::AttributesField>(details); - return IsNotSetWord32(attributes, PropertyAttributes::DONT_ENUM); -} - -TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindAccessor( - TNode<Uint32T> kind) { - return Word32Equal(kind, Int32Constant(PropertyKind::kAccessor)); -} - -TNode<BoolT> ObjectEntriesValuesBuiltinsAssembler::IsPropertyKindData( - TNode<Uint32T> kind) { - return Word32Equal(kind, Int32Constant(PropertyKind::kData)); -} - -TNode<Uint32T> ObjectEntriesValuesBuiltinsAssembler::HasHiddenPrototype( - TNode<Map> map) { - TNode<Uint32T> bit_field3 = LoadMapBitField3(map); - return DecodeWord32<Map::HasHiddenPrototypeBit>(bit_field3); -} - -void ObjectEntriesValuesBuiltinsAssembler::GetOwnValuesOrEntries( - TNode<Context> context, TNode<Object> maybe_object, - CollectType collect_type) { - TNode<JSObject> object = TNode<JSObject>::UncheckedCast( - CallBuiltin(Builtins::kToObject, context, maybe_object)); - - Label if_call_runtime_with_fast_path(this, Label::kDeferred), - if_call_runtime(this, Label::kDeferred), - if_no_properties(this, Label::kDeferred); - - TNode<Map> map = LoadMap(object); - GotoIfNot(IsJSObjectMap(map), &if_call_runtime); - GotoIfMapHasSlowProperties(map, &if_call_runtime); - - TNode<FixedArrayBase> elements = LoadElements(object); - // If the object has elements, we treat it as slow case. - // So, we go to runtime call. - GotoIfNot(IsEmptyFixedArray(elements), &if_call_runtime_with_fast_path); - - TNode<JSArray> result = FastGetOwnValuesOrEntries( - context, object, &if_call_runtime_with_fast_path, &if_no_properties, - collect_type); - Return(result); - - BIND(&if_no_properties); - { - Node* native_context = LoadNativeContext(context); - Node* array_map = LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - Node* empty_array = AllocateJSArray(PACKED_ELEMENTS, array_map, - IntPtrConstant(0), SmiConstant(0)); - Return(empty_array); - } - - BIND(&if_call_runtime_with_fast_path); - { - // In slow case, we simply call runtime. - if (collect_type == CollectType::kEntries) { - Return(CallRuntime(Runtime::kObjectEntries, context, object)); - } else { - DCHECK(collect_type == CollectType::kValues); - Return(CallRuntime(Runtime::kObjectValues, context, object)); - } - } - - BIND(&if_call_runtime); - { - // In slow case, we simply call runtime. - if (collect_type == CollectType::kEntries) { - Return(CallRuntime(Runtime::kObjectEntriesSkipFastPath, context, object)); - } else { - DCHECK(collect_type == CollectType::kValues); - Return(CallRuntime(Runtime::kObjectValuesSkipFastPath, context, object)); - } - } -} - -void ObjectEntriesValuesBuiltinsAssembler::GotoIfMapHasSlowProperties( - TNode<Map> map, Label* if_slow) { - GotoIf(IsStringWrapperElementsKind(map), if_slow); - GotoIf(IsSpecialReceiverMap(map), if_slow); - GotoIf(HasHiddenPrototype(map), if_slow); - GotoIf(IsDictionaryMap(map), if_slow); -} - -TNode<JSArray> ObjectEntriesValuesBuiltinsAssembler::FastGetOwnValuesOrEntries( - TNode<Context> context, TNode<JSObject> object, - Label* if_call_runtime_with_fast_path, Label* if_no_properties, - CollectType collect_type) { - Node* native_context = LoadNativeContext(context); - TNode<Map> array_map = - LoadJSArrayElementsMap(PACKED_ELEMENTS, native_context); - TNode<Map> map = LoadMap(object); - TNode<Uint32T> bit_field3 = LoadMapBitField3(map); - - Label if_has_enum_cache(this), if_not_has_enum_cache(this), - collect_entries(this); - Node* object_enum_length = - DecodeWordFromWord32<Map::EnumLengthBits>(bit_field3); - Node* has_enum_cache = WordNotEqual( - object_enum_length, IntPtrConstant(kInvalidEnumCacheSentinel)); - - // In case, we found enum_cache in object, - // we use it as array_length becuase it has same size for - // Object.(entries/values) result array object length. - // So object_enum_length use less memory space than - // NumberOfOwnDescriptorsBits value. - // And in case, if enum_cache_not_found, - // we call runtime and initialize enum_cache for subsequent call of - // CSA fast path. - Branch(has_enum_cache, &if_has_enum_cache, if_call_runtime_with_fast_path); - - BIND(&if_has_enum_cache); - { - GotoIf(WordEqual(object_enum_length, IntPtrConstant(0)), if_no_properties); - TNode<FixedArray> values_or_entries = TNode<FixedArray>::UncheckedCast( - AllocateFixedArray(PACKED_ELEMENTS, object_enum_length, - INTPTR_PARAMETERS, kAllowLargeObjectAllocation)); - - // If in case we have enum_cache, - // we can't detect accessor of object until loop through descritpros. - // So if object might have accessor, - // we will remain invalid addresses of FixedArray. - // Because in that case, we need to jump to runtime call. - // So the array filled by the-hole even if enum_cache exists. - FillFixedArrayWithValue(PACKED_ELEMENTS, values_or_entries, - IntPtrConstant(0), object_enum_length, - Heap::kTheHoleValueRootIndex); - - TVARIABLE(IntPtrT, var_result_index, IntPtrConstant(0)); - TVARIABLE(IntPtrT, var_descriptor_index, IntPtrConstant(0)); - Variable* vars[] = {&var_descriptor_index, &var_result_index}; - // Let desc be ? O.[[GetOwnProperty]](key). - TNode<DescriptorArray> descriptors = LoadMapDescriptors(map); - Label loop(this, 2, vars), after_loop(this), loop_condition(this); - Branch(IntPtrEqual(var_descriptor_index, object_enum_length), &after_loop, - &loop); - - // We dont use BuildFastLoop. - // Instead, we use hand-written loop - // because of we need to use 'continue' functionality. - BIND(&loop); - { - // Currently, we will not invoke getters, - // so, map will not be changed. - CSA_ASSERT(this, WordEqual(map, LoadMap(object))); - TNode<Uint32T> descriptor_index = TNode<Uint32T>::UncheckedCast( - TruncateWordToWord32(var_descriptor_index)); - Node* next_key = DescriptorArrayGetKey(descriptors, descriptor_index); - - // Skip Symbols. - GotoIf(IsSymbol(next_key), &loop_condition); - - TNode<Uint32T> details = TNode<Uint32T>::UncheckedCast( - DescriptorArrayGetDetails(descriptors, descriptor_index)); - TNode<Uint32T> kind = LoadPropertyKind(details); - - // If property is accessor, we escape fast path and call runtime. - GotoIf(IsPropertyKindAccessor(kind), if_call_runtime_with_fast_path); - CSA_ASSERT(this, IsPropertyKindData(kind)); - - // If desc is not undefined and desc.[[Enumerable]] is true, then - GotoIfNot(IsPropertyEnumerable(details), &loop_condition); - - VARIABLE(var_property_value, MachineRepresentation::kTagged, - UndefinedConstant()); - Node* descriptor_name_index = DescriptorNumberToIndex(descriptor_index); - - // Let value be ? Get(O, key). - LoadPropertyFromFastObject(object, map, descriptors, - descriptor_name_index, details, - &var_property_value); - - // If kind is "value", append value to properties. - Node* value = var_property_value.value(); - - if (collect_type == CollectType::kEntries) { - // Let entry be CreateArrayFromList(« key, value »). - Node* array = nullptr; - Node* elements = nullptr; - std::tie(array, elements) = AllocateUninitializedJSArrayWithElements( - PACKED_ELEMENTS, array_map, SmiConstant(2), nullptr, - IntPtrConstant(2)); - StoreFixedArrayElement(elements, 0, next_key, SKIP_WRITE_BARRIER); - StoreFixedArrayElement(elements, 1, value, SKIP_WRITE_BARRIER); - value = array; - } - - StoreFixedArrayElement(values_or_entries, var_result_index, value); - Increment(&var_result_index, 1); - Goto(&loop_condition); - - BIND(&loop_condition); - { - Increment(&var_descriptor_index, 1); - Branch(IntPtrEqual(var_descriptor_index, object_enum_length), - &after_loop, &loop); - } - } - BIND(&after_loop); - return FinalizeValuesOrEntriesJSArray(context, values_or_entries, - var_result_index, array_map, - if_no_properties); - } -} - -TNode<JSArray> -ObjectEntriesValuesBuiltinsAssembler::FinalizeValuesOrEntriesJSArray( - TNode<Context> context, TNode<FixedArray> result, TNode<IntPtrT> size, - TNode<Map> array_map, Label* if_empty) { - CSA_ASSERT(this, IsJSArrayMap(array_map)); - - GotoIf(IntPtrEqual(size, IntPtrConstant(0)), if_empty); - Node* array = AllocateUninitializedJSArrayWithoutElements( - array_map, SmiTag(size), nullptr); - StoreObjectField(array, JSArray::kElementsOffset, result); - return TNode<JSArray>::UncheckedCast(array); -} - TF_BUILTIN(ObjectPrototypeToLocaleString, CodeStubAssembler) { TNode<Context> context = CAST(Parameter(Descriptor::kContext)); TNode<Object> receiver = CAST(Parameter(Descriptor::kReceiver)); @@ -551,22 +266,6 @@ TF_BUILTIN(ObjectKeys, ObjectBuiltinsAssembler) { } } -TF_BUILTIN(ObjectValues, ObjectEntriesValuesBuiltinsAssembler) { - TNode<JSObject> object = - TNode<JSObject>::UncheckedCast(Parameter(Descriptor::kObject)); - TNode<Context> context = - TNode<Context>::UncheckedCast(Parameter(Descriptor::kContext)); - GetOwnValuesOrEntries(context, object, CollectType::kValues); -} - -TF_BUILTIN(ObjectEntries, ObjectEntriesValuesBuiltinsAssembler) { - TNode<JSObject> object = - TNode<JSObject>::UncheckedCast(Parameter(Descriptor::kObject)); - TNode<Context> context = - TNode<Context>::UncheckedCast(Parameter(Descriptor::kContext)); - GetOwnValuesOrEntries(context, object, CollectType::kEntries); -} - // ES #sec-object.prototype.isprototypeof TF_BUILTIN(ObjectPrototypeIsPrototypeOf, ObjectBuiltinsAssembler) { Node* receiver = Parameter(Descriptor::kReceiver); diff --git a/chromium/v8/src/builtins/builtins-object.cc b/chromium/v8/src/builtins/builtins-object.cc index 4e353b92600..36f7ebfc0a8 100644 --- a/chromium/v8/src/builtins/builtins-object.cc +++ b/chromium/v8/src/builtins/builtins-object.cc @@ -395,6 +395,31 @@ BUILTIN(ObjectIsSealed) { return isolate->heap()->ToBoolean(result.FromJust()); } +BUILTIN(ObjectValues) { + HandleScope scope(isolate); + Handle<Object> object = args.atOrUndefined(isolate, 1); + Handle<JSReceiver> receiver; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, + Object::ToObject(isolate, object)); + Handle<FixedArray> values; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, values, JSReceiver::GetOwnValues(receiver, ENUMERABLE_STRINGS)); + return *isolate->factory()->NewJSArrayWithElements(values); +} + +BUILTIN(ObjectEntries) { + HandleScope scope(isolate); + Handle<Object> object = args.atOrUndefined(isolate, 1); + Handle<JSReceiver> receiver; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION(isolate, receiver, + Object::ToObject(isolate, object)); + Handle<FixedArray> entries; + ASSIGN_RETURN_FAILURE_ON_EXCEPTION( + isolate, entries, + JSReceiver::GetOwnEntries(receiver, ENUMERABLE_STRINGS)); + return *isolate->factory()->NewJSArrayWithElements(entries); +} + BUILTIN(ObjectGetOwnPropertyDescriptors) { HandleScope scope(isolate); Handle<Object> object = args.atOrUndefined(isolate, 1); diff --git a/chromium/v8/src/code-stub-assembler.cc b/chromium/v8/src/code-stub-assembler.cc index f98e7fe5192..2027d208abc 100644 --- a/chromium/v8/src/code-stub-assembler.cc +++ b/chromium/v8/src/code-stub-assembler.cc @@ -4019,6 +4019,19 @@ Node* CodeStubAssembler::InstanceTypeEqual(Node* instance_type, int type) { return Word32Equal(instance_type, Int32Constant(type)); } +Node* CodeStubAssembler::IsSpecialReceiverMap(Node* map) { + CSA_SLOW_ASSERT(this, IsMap(map)); + Node* is_special = IsSpecialReceiverInstanceType(LoadMapInstanceType(map)); + uint32_t mask = + Map::HasNamedInterceptorBit::kMask | Map::IsAccessCheckNeededBit::kMask; + USE(mask); + // Interceptors or access checks imply special receiver. + CSA_ASSERT(this, + SelectConstant(IsSetWord32(LoadMapBitField(map), mask), is_special, + Int32Constant(1), MachineRepresentation::kWord32)); + return is_special; +} + TNode<BoolT> CodeStubAssembler::IsDictionaryMap(SloppyTNode<Map> map) { CSA_SLOW_ASSERT(this, IsMap(map)); Node* bit_field3 = LoadMapBitField3(map); @@ -6369,38 +6382,36 @@ Node* CodeStubAssembler::DescriptorArrayNumberOfEntries(Node* descriptors) { descriptors, IntPtrConstant(DescriptorArray::kDescriptorLengthIndex)); } -Node* CodeStubAssembler::DescriptorNumberToIndex( - SloppyTNode<Uint32T> descriptor_number) { - Node* descriptor_size = Int32Constant(DescriptorArray::kEntrySize); - Node* index = Int32Mul(descriptor_number, descriptor_size); - return ChangeInt32ToIntPtr(index); +namespace { + +Node* DescriptorNumberToIndex(CodeStubAssembler* a, Node* descriptor_number) { + Node* descriptor_size = a->Int32Constant(DescriptorArray::kEntrySize); + Node* index = a->Int32Mul(descriptor_number, descriptor_size); + return a->ChangeInt32ToIntPtr(index); } +} // namespace + Node* CodeStubAssembler::DescriptorArrayToKeyIndex(Node* descriptor_number) { return IntPtrAdd(IntPtrConstant(DescriptorArray::ToKeyIndex(0)), - DescriptorNumberToIndex(descriptor_number)); + DescriptorNumberToIndex(this, descriptor_number)); } Node* CodeStubAssembler::DescriptorArrayGetSortedKeyIndex( Node* descriptors, Node* descriptor_number) { - Node* details = DescriptorArrayGetDetails( - TNode<DescriptorArray>::UncheckedCast(descriptors), - TNode<Uint32T>::UncheckedCast(descriptor_number)); + const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; + Node* details = LoadAndUntagToWord32FixedArrayElement( + descriptors, DescriptorNumberToIndex(this, descriptor_number), + details_offset); return DecodeWord32<PropertyDetails::DescriptorPointer>(details); } Node* CodeStubAssembler::DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number) { const int key_offset = DescriptorArray::ToKeyIndex(0) * kPointerSize; - return LoadFixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), key_offset); -} - -TNode<Uint32T> CodeStubAssembler::DescriptorArrayGetDetails( - TNode<DescriptorArray> descriptors, TNode<Uint32T> descriptor_number) { - const int details_offset = DescriptorArray::ToDetailsIndex(0) * kPointerSize; - return TNode<Uint32T>::UncheckedCast(LoadAndUntagToWord32FixedArrayElement( - descriptors, DescriptorNumberToIndex(descriptor_number), details_offset)); + return LoadFixedArrayElement(descriptors, + DescriptorNumberToIndex(this, descriptor_number), + key_offset); } void CodeStubAssembler::DescriptorLookupBinary(Node* unique_name, @@ -6599,22 +6610,12 @@ void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map, Variable* var_value) { DCHECK_EQ(MachineRepresentation::kWord32, var_details->rep()); DCHECK_EQ(MachineRepresentation::kTagged, var_value->rep()); + Comment("[ LoadPropertyFromFastObject"); Node* details = LoadDetailsByKeyIndex<DescriptorArray>(descriptors, name_index); var_details->Bind(details); - LoadPropertyFromFastObject(object, map, descriptors, name_index, details, - var_value); -} - -void CodeStubAssembler::LoadPropertyFromFastObject(Node* object, Node* map, - Node* descriptors, - Node* name_index, - Node* details, - Variable* var_value) { - Comment("[ LoadPropertyFromFastObject"); - Node* location = DecodeWord32<PropertyDetails::LocationField>(details); Label if_in_field(this), if_in_descriptor(this), done(this); diff --git a/chromium/v8/src/code-stub-assembler.h b/chromium/v8/src/code-stub-assembler.h index 4a72b203a78..0dd7a35c4a0 100644 --- a/chromium/v8/src/code-stub-assembler.h +++ b/chromium/v8/src/code-stub-assembler.h @@ -1125,6 +1125,7 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* IsSequentialStringInstanceType(Node* instance_type); Node* IsShortExternalStringInstanceType(Node* instance_type); Node* IsSpecialReceiverInstanceType(Node* instance_type); + Node* IsSpecialReceiverMap(Node* map); Node* IsSpeciesProtectorCellInvalid(); Node* IsStringInstanceType(Node* instance_type); Node* IsString(Node* object); @@ -1583,10 +1584,6 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { Node* name_index, Variable* var_details, Variable* var_value); - void LoadPropertyFromFastObject(Node* object, Node* map, Node* descriptors, - Node* name_index, Node* details, - Variable* var_value); - void LoadPropertyFromNameDictionary(Node* dictionary, Node* entry, Variable* var_details, Variable* var_value); @@ -1909,15 +1906,11 @@ class V8_EXPORT_PRIVATE CodeStubAssembler : public compiler::CodeAssembler { void DescriptorLookupBinary(Node* unique_name, Node* descriptors, Node* nof, Label* if_found, Variable* var_name_index, Label* if_not_found); - Node* DescriptorNumberToIndex(SloppyTNode<Uint32T> descriptor_number); // Implements DescriptorArray::ToKeyIndex. // Returns an untagged IntPtr. Node* DescriptorArrayToKeyIndex(Node* descriptor_number); // Implements DescriptorArray::GetKey. Node* DescriptorArrayGetKey(Node* descriptors, Node* descriptor_number); - // Implements DescriptorArray::GetKey. - TNode<Uint32T> DescriptorArrayGetDetails(TNode<DescriptorArray> descriptors, - TNode<Uint32T> descriptor_number); Node* CallGetterIfAccessor(Node* value, Node* details, Node* context, Node* receiver, Label* if_bailout, diff --git a/chromium/v8/src/compiler/escape-analysis.cc b/chromium/v8/src/compiler/escape-analysis.cc index 4b773136a92..984c5133968 100644 --- a/chromium/v8/src/compiler/escape-analysis.cc +++ b/chromium/v8/src/compiler/escape-analysis.cc @@ -623,9 +623,7 @@ void ReduceNode(const Operator* op, EscapeAnalysisTracker::Scope* current, break; } case IrOpcode::kTypeGuard: { - // The type-guard is re-introduced in the final reducer if the types - // don't match. - current->SetReplacement(current->ValueInput(0)); + current->SetVirtualObject(current->ValueInput(0)); break; } case IrOpcode::kReferenceEqual: { diff --git a/chromium/v8/src/debug/debug-evaluate.cc b/chromium/v8/src/debug/debug-evaluate.cc index 33bc81e5f74..e5865e639c3 100644 --- a/chromium/v8/src/debug/debug-evaluate.cc +++ b/chromium/v8/src/debug/debug-evaluate.cc @@ -343,11 +343,7 @@ bool IntrinsicHasNoSideEffect(Runtime::FunctionId id) { V(AllocateSeqOneByteString) \ V(AllocateSeqTwoByteString) \ V(ObjectCreate) \ - V(ObjectEntries) \ - V(ObjectEntriesSkipFastPath) \ V(ObjectHasOwnProperty) \ - V(ObjectValues) \ - V(ObjectValuesSkipFastPath) \ V(ArrayIndexOf) \ V(ArrayIncludes_Slow) \ V(ArrayIsArray) \ diff --git a/chromium/v8/src/field-index.h b/chromium/v8/src/field-index.h index 428ad52cc2d..9e390e3d465 100644 --- a/chromium/v8/src/field-index.h +++ b/chromium/v8/src/field-index.h @@ -123,7 +123,8 @@ class FieldIndex final { }; // Offset of first inobject property from beginning of object. class FirstInobjectPropertyOffsetBits - : public BitField64<int, InObjectPropertyBits::kNext, 7> {}; + : public BitField64<int, InObjectPropertyBits::kNext, + kFirstInobjectPropertyOffsetBitCount> {}; class IsHiddenField : public BitField64<bool, FirstInobjectPropertyOffsetBits::kNext, 1> {}; STATIC_ASSERT(IsHiddenField::kNext <= 64); diff --git a/chromium/v8/src/objects-inl.h b/chromium/v8/src/objects-inl.h index c3841aa63e7..1cbc2ca418e 100644 --- a/chromium/v8/src/objects-inl.h +++ b/chromium/v8/src/objects-inl.h @@ -2431,6 +2431,7 @@ int ObjectTemplateInfo::embedder_field_count() const { } void ObjectTemplateInfo::set_embedder_field_count(int count) { + DCHECK_LE(count, JSObject::kMaxEmbedderFields); return set_data( Smi::FromInt(EmbedderFieldCount::update(Smi::ToInt(data()), count))); } diff --git a/chromium/v8/src/objects.cc b/chromium/v8/src/objects.cc index f8c55e57a63..af2e3eccb37 100644 --- a/chromium/v8/src/objects.cc +++ b/chromium/v8/src/objects.cc @@ -8791,10 +8791,9 @@ MUST_USE_RESULT Maybe<bool> FastGetOwnValuesOrEntries( MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate, Handle<JSReceiver> object, PropertyFilter filter, - bool try_fast_path, bool get_entries) { Handle<FixedArray> values_or_entries; - if (try_fast_path && filter == ENUMERABLE_STRINGS) { + if (filter == ENUMERABLE_STRINGS) { Maybe<bool> fast_values_or_entries = FastGetOwnValuesOrEntries( isolate, object, get_entries, &values_or_entries); if (fast_values_or_entries.IsNothing()) return MaybeHandle<FixedArray>(); @@ -8847,17 +8846,13 @@ MaybeHandle<FixedArray> GetOwnValuesOrEntries(Isolate* isolate, } MaybeHandle<FixedArray> JSReceiver::GetOwnValues(Handle<JSReceiver> object, - PropertyFilter filter, - bool try_fast_path) { - return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, - try_fast_path, false); + PropertyFilter filter) { + return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, false); } MaybeHandle<FixedArray> JSReceiver::GetOwnEntries(Handle<JSReceiver> object, - PropertyFilter filter, - bool try_fast_path) { - return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, - try_fast_path, true); + PropertyFilter filter) { + return GetOwnValuesOrEntries(object->GetIsolate(), object, filter, true); } bool Map::DictionaryElementsInPrototypeChainOnly() { @@ -13783,18 +13778,24 @@ void JSFunction::CalculateInstanceSizeHelper(InstanceType instance_type, int requested_in_object_properties, int* instance_size, int* in_object_properties) { + DCHECK_LE(static_cast<unsigned>(requested_embedder_fields), + JSObject::kMaxEmbedderFields); int header_size = JSObject::GetHeaderSize(instance_type, has_prototype_slot); int max_nof_fields = (JSObject::kMaxInstanceSize - header_size) >> kPointerSizeLog2; CHECK_LE(max_nof_fields, JSObject::kMaxInObjectProperties); - *in_object_properties = Min(requested_in_object_properties, max_nof_fields); - CHECK_LE(requested_embedder_fields, max_nof_fields - *in_object_properties); + CHECK_LE(static_cast<unsigned>(requested_embedder_fields), + static_cast<unsigned>(max_nof_fields)); + *in_object_properties = Min(requested_in_object_properties, + max_nof_fields - requested_embedder_fields); *instance_size = header_size + ((requested_embedder_fields + *in_object_properties) << kPointerSizeLog2); CHECK_EQ(*in_object_properties, ((*instance_size - header_size) >> kPointerSizeLog2) - requested_embedder_fields); + CHECK_LE(static_cast<unsigned>(*instance_size), + static_cast<unsigned>(JSObject::kMaxInstanceSize)); } // static diff --git a/chromium/v8/src/objects.h b/chromium/v8/src/objects.h index 93f4a4eb95b..c4e3d972e11 100644 --- a/chromium/v8/src/objects.h +++ b/chromium/v8/src/objects.h @@ -2182,12 +2182,10 @@ class JSReceiver: public HeapObject { Handle<JSReceiver> object); MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnValues( - Handle<JSReceiver> object, PropertyFilter filter, - bool try_fast_path = true); + Handle<JSReceiver> object, PropertyFilter filter); MUST_USE_RESULT static MaybeHandle<FixedArray> GetOwnEntries( - Handle<JSReceiver> object, PropertyFilter filter, - bool try_fast_path = true); + Handle<JSReceiver> object, PropertyFilter filter); static const int kHashMask = PropertyArray::HashField::kMask; @@ -2673,6 +2671,11 @@ class JSObject: public JSReceiver { static const int kMaxInObjectProperties = (kMaxInstanceSize - kHeaderSize) >> kPointerSizeLog2; STATIC_ASSERT(kMaxInObjectProperties <= kMaxNumberOfDescriptors); + // TODO(cbruni): Revisit calculation of the max supported embedder fields. + static const int kMaxEmbedderFields = + ((1 << kFirstInobjectPropertyOffsetBitCount) - 1 - kHeaderSize) >> + kPointerSizeLog2; + STATIC_ASSERT(kMaxEmbedderFields <= kMaxInObjectProperties); class BodyDescriptor; // No weak fields. diff --git a/chromium/v8/src/profiler/cpu-profiler.cc b/chromium/v8/src/profiler/cpu-profiler.cc index ac8f55a89b5..a915ebd5119 100644 --- a/chromium/v8/src/profiler/cpu-profiler.cc +++ b/chromium/v8/src/profiler/cpu-profiler.cc @@ -165,13 +165,16 @@ void ProfilerEventsProcessor::Run() { if (nextSampleTime > now) { #if V8_OS_WIN - // Do not use Sleep on Windows as it is very imprecise. - // Could be up to 16ms jitter, which is unacceptable for the purpose. - while (base::TimeTicks::HighResolutionNow() < nextSampleTime) { - } -#else - base::OS::Sleep(nextSampleTime - now); + if (nextSampleTime - now < base::TimeDelta::FromMilliseconds(100)) { + // Do not use Sleep on Windows as it is very imprecise, with up to 16ms + // jitter, which is unacceptable for short profile intervals. + while (base::TimeTicks::HighResolutionNow() < nextSampleTime) { + } + } else // NOLINT #endif + { + base::OS::Sleep(nextSampleTime - now); + } } // Schedule next sample. sampler_ is nullptr in tests. diff --git a/chromium/v8/src/property-details.h b/chromium/v8/src/property-details.h index 34c43047f84..dbd4f93acd2 100644 --- a/chromium/v8/src/property-details.h +++ b/chromium/v8/src/property-details.h @@ -197,6 +197,7 @@ class Representation { static const int kDescriptorIndexBitCount = 10; +static const int kFirstInobjectPropertyOffsetBitCount = 7; // The maximum number of descriptors we want in a descriptor array. It should // fit in a page and also the following should hold: // kMaxNumberOfDescriptors + kFieldsAdded <= PropertyArray::kMaxLength. diff --git a/chromium/v8/src/runtime/runtime-object.cc b/chromium/v8/src/runtime/runtime-object.cc index 379472bdbea..057ead94078 100644 --- a/chromium/v8/src/runtime/runtime-object.cc +++ b/chromium/v8/src/runtime/runtime-object.cc @@ -439,61 +439,6 @@ RUNTIME_FUNCTION(Runtime_OptimizeObjectForAddingMultipleProperties) { return *object; } -RUNTIME_FUNCTION(Runtime_ObjectValues) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle<FixedArray> values; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, values, - JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS, - true)); - return *isolate->factory()->NewJSArrayWithElements(values); -} - -RUNTIME_FUNCTION(Runtime_ObjectValuesSkipFastPath) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle<FixedArray> value; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, value, - JSReceiver::GetOwnValues(receiver, PropertyFilter::ENUMERABLE_STRINGS, - false)); - return *isolate->factory()->NewJSArrayWithElements(value); -} - -RUNTIME_FUNCTION(Runtime_ObjectEntries) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle<FixedArray> entries; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, entries, - JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS, - true)); - return *isolate->factory()->NewJSArrayWithElements(entries); -} - -RUNTIME_FUNCTION(Runtime_ObjectEntriesSkipFastPath) { - HandleScope scope(isolate); - DCHECK_EQ(1, args.length()); - - CONVERT_ARG_HANDLE_CHECKED(JSReceiver, receiver, 0); - - Handle<FixedArray> entries; - ASSIGN_RETURN_FAILURE_ON_EXCEPTION( - isolate, entries, - JSReceiver::GetOwnEntries(receiver, PropertyFilter::ENUMERABLE_STRINGS, - false)); - return *isolate->factory()->NewJSArrayWithElements(entries); -} RUNTIME_FUNCTION(Runtime_GetProperty) { HandleScope scope(isolate); diff --git a/chromium/v8/src/runtime/runtime.h b/chromium/v8/src/runtime/runtime.h index 487ee675ad3..d05f4984c6a 100644 --- a/chromium/v8/src/runtime/runtime.h +++ b/chromium/v8/src/runtime/runtime.h @@ -391,10 +391,6 @@ namespace internal { F(ObjectCreate, 2, 1) \ F(InternalSetPrototype, 2, 1) \ F(OptimizeObjectForAddingMultipleProperties, 2, 1) \ - F(ObjectValues, 1, 1) \ - F(ObjectValuesSkipFastPath, 1, 1) \ - F(ObjectEntries, 1, 1) \ - F(ObjectEntriesSkipFastPath, 1, 1) \ F(GetProperty, 2, 1) \ F(KeyedGetProperty, 2, 1) \ F(AddNamedProperty, 4, 1) \ diff --git a/chromium/v8/src/simulator-base.h b/chromium/v8/src/simulator-base.h index 27dc87d0503..84c1f2fd5b8 100644 --- a/chromium/v8/src/simulator-base.h +++ b/chromium/v8/src/simulator-base.h @@ -43,6 +43,26 @@ class SimulatorBase { return ConvertReturn<Return>(ret); } + // Convert back integral return types. + template <typename T> + static typename std::enable_if<std::is_integral<T>::value, T>::type + ConvertReturn(intptr_t ret) { + static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize"); + return static_cast<T>(ret); + } + + // Convert back pointer-typed return types. + template <typename T> + static typename std::enable_if<std::is_pointer<T>::value, T>::type + ConvertReturn(intptr_t ret) { + return reinterpret_cast<T>(ret); + } + + // Convert back void return type (i.e. no return). + template <typename T> + static typename std::enable_if<std::is_void<T>::value, T>::type ConvertReturn( + intptr_t ret) {} + private: // Runtime call support. Uses the isolate in a thread-safe way. static void* RedirectExternalReference(Isolate* isolate, @@ -69,26 +89,6 @@ class SimulatorBase { ConvertArg(T arg) { return reinterpret_cast<intptr_t>(arg); } - - // Convert back integral return types. - template <typename T> - static typename std::enable_if<std::is_integral<T>::value, T>::type - ConvertReturn(intptr_t ret) { - static_assert(sizeof(T) <= sizeof(intptr_t), "type bigger than ptrsize"); - return static_cast<T>(ret); - } - - // Convert back pointer-typed return types. - template <typename T> - static typename std::enable_if<std::is_pointer<T>::value, T>::type - ConvertReturn(intptr_t ret) { - return reinterpret_cast<T>(ret); - } - - // Convert back void return type (i.e. no return). - template <typename T> - static typename std::enable_if<std::is_void<T>::value, T>::type ConvertReturn( - intptr_t ret) {} }; // When the generated code calls an external reference we need to catch that in diff --git a/chromium/v8/src/wasm/wasm-code-manager.cc b/chromium/v8/src/wasm/wasm-code-manager.cc index 8e46f33b012..2b8f3097339 100644 --- a/chromium/v8/src/wasm/wasm-code-manager.cc +++ b/chromium/v8/src/wasm/wasm-code-manager.cc @@ -954,6 +954,8 @@ void WasmCodeManager::FreeNativeModuleMemories(NativeModule* native_module) { Free(&vmem); DCHECK(!vmem.IsReserved()); } + native_module->owned_memory_.clear(); + // No need to tell the GC anything if we're destroying the heap, // which we currently indicate by having the isolate_ as null if (isolate_ == nullptr) return; diff --git a/chromium/v8/tools/whitespace.txt b/chromium/v8/tools/whitespace.txt index ed5e51f96a6..83f006688cd 100644 --- a/chromium/v8/tools/whitespace.txt +++ b/chromium/v8/tools/whitespace.txt @@ -8,5 +8,3 @@ The doubles heard this and started to unbox. The Smi looked at them when a crazy v8-autoroll account showed up... The autoroller bought a round of Himbeerbrause. Suddenly... The bartender starts to shake the bottles....................... -. -. |