Commit 17f4e7d2 authored by Timothy Gu's avatar Timothy Gu Committed by Commit Bot

Reland "bindings: Implement timers with V8Function"

This is a reland of 254369a5. It addresses bug
888025 by adding ASAN test expectations, as the relevant V8 feature does not
yet support running on ASAN builds.

Original change's description:
> bindings: Implement timers with V8Function
>
> This fixes bug 866610 by using the IDL infrastructure to properly enter
> the v8::Context before calling the registered callback.
>
> Also ensure eager finalization of ScheduledAction in DOMTimer to
> prevent a memory leak. Added two more effective DCHECKs to confirm.
>
> Bug: 866610
> Change-Id: I37d7bd05f035fe31856cfe68bae51aa0632cd3b1
> Reviewed-on: https://chromium-review.googlesource.com/1220486
> Reviewed-by: Nate Chapin <japhet@chromium.org>
> Reviewed-by: Yuki Shiino <yukishiino@chromium.org>
> Reviewed-by: Hitoshi Yoshida <peria@chromium.org>
> Commit-Queue: Timothy Gu <timothygu@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#593108}

TBR=japhet@chromium.org

Bug: 866610, 888025
Change-Id: Iee5c1d6917ad7770383e06a425f96000835a663a
Reviewed-on: https://chromium-review.googlesource.com/c/1239624Reviewed-by: default avatarNate Chapin <japhet@chromium.org>
Reviewed-by: default avatarHitoshi Yoshida <peria@chromium.org>
Reviewed-by: default avatarKentaro Hara <haraken@chromium.org>
Reviewed-by: default avatarYuki Shiino <yukishiino@chromium.org>
Commit-Queue: Timothy Gu <timothygu@chromium.org>
Cr-Commit-Position: refs/heads/master@{#601830}
parent 2819b865
...@@ -88,3 +88,25 @@ crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/ ...@@ -88,3 +88,25 @@ crbug.com/838057 [ Linux ] virtual/outofblink-cors/external/wpt/service-workers/
# Disabled by sheriff due to test crash # Disabled by sheriff due to test crash
crbug.com/896068 [ Linux ] webaudio/AudioBuffer/huge-buffer.html [ Crash ] crbug.com/896068 [ Linux ] webaudio/AudioBuffer/huge-buffer.html [ Crash ]
crbug.com/896068 [ Linux ] webaudio/dom-exceptions.html [ Pass Crash ] crbug.com/896068 [ Linux ] webaudio/dom-exceptions.html [ Pass Crash ]
# V8's incumbent context tracking does not work with ASAN yet
crbug.com/888867 external/wpt/html/browsers/browsing-the-web/unloading-documents/beforeunload-canceling.html [ Timeout ]
crbug.com/888867 external/wpt/html/browsers/browsing-the-web/unloading-documents/unload/007.html [ Timeout ]
crbug.com/888867 external/wpt/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_3.html [ Timeout ]
crbug.com/888867 external/wpt/html/browsers/the-window-object/garbage-collection-and-browsing-contexts/discard_iframe_history_4.html [ Timeout ]
crbug.com/888867 external/wpt/html/webappapis/dynamic-markup-insertion/opening-the-input-stream/url-entry-document.window.html [ Timeout ]
crbug.com/888867 external/wpt/xhr/open-url-multi-window-2.htm [ Timeout ]
crbug.com/888867 external/wpt/xhr/open-url-multi-window-3.htm [ Timeout ]
crbug.com/888867 fast/forms/calendar-picker/calendar-picker-type-change-onchange.html [ Timeout ]
crbug.com/888867 http/tests/appcache/crash-when-navigating-away-then-back.html [ Timeout ]
crbug.com/888867 http/tests/devtools/sources/debugger-pause/debugger-resume-button-in-overlay.js [ Timeout ]
crbug.com/888867 http/tests/loading/onbeforeunload-detach.html [ Timeout ]
crbug.com/888867 http/tests/loading/onreadystatechange-detach.html [ Timeout ]
crbug.com/888867 http/tests/misc/delete-frame-during-readystatechange-with-gc-after-video-removal.html [ Timeout ]
crbug.com/888867 http/tests/misc/delete-frame-during-readystatechange.html [ Timeout ]
crbug.com/888867 http/tests/misc/frame-detached-in-animationstart-event.html [ Timeout ]
crbug.com/888867 http/tests/workers/shared-worker-lifecycle.html [ Timeout ]
crbug.com/888867 virtual/outofblink-cors/external/wpt/xhr/open-url-multi-window-2.htm [ Timeout ]
crbug.com/888867 virtual/outofblink-cors/external/wpt/xhr/open-url-multi-window-3.htm [ Timeout ]
crbug.com/888867 virtual/outofblink-cors-ns/external/wpt/xhr/open-url-multi-window-2.htm [ Timeout ]
crbug.com/888867 virtual/outofblink-cors-ns/external/wpt/xhr/open-url-multi-window-3.htm [ Timeout ]
async_test(t => {
const frame = document.body.appendChild(document.createElement("iframe"));
t.add_cleanup(() => frame.remove());
const frameURL = new URL("resources/url-entry-document-timer-frame.html", document.URL).href;
window.timerTest = t.step_func_done(() => {
assert_equals(frame.contentDocument.URL, frameURL);
assert_equals(frame.contentWindow.location.href, frameURL);
// In this case, the entry settings object was set when this function is
// executed in the timer task through Web IDL's "invoke a callback
// function" algorithm, to be the relevant settings object of this
// function. Therefore the URL of this document would be inherited.
assert_equals(frame.contentDocument.open(), frame.contentDocument);
assert_equals(frame.contentDocument.URL, document.URL);
assert_equals(frame.contentWindow.location.href, document.URL);
});
frame.src = frameURL;
}, "document.open() changes document's URL to the entry settings object's responsible document's (through timeouts)");
...@@ -163,6 +163,7 @@ SET TIMEOUT: html/semantics/embedded-content/the-img-element/* ...@@ -163,6 +163,7 @@ SET TIMEOUT: html/semantics/embedded-content/the-img-element/*
SET TIMEOUT: html/semantics/scripting-1/the-script-element/* SET TIMEOUT: html/semantics/scripting-1/the-script-element/*
SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/0* SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/0*
SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/history-frame.html SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/history-frame.html
SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/resources/url-entry-document-timer-frame.html
SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/tasks.window.js SET TIMEOUT: html/webappapis/dynamic-markup-insertion/opening-the-input-stream/tasks.window.js
SET TIMEOUT: html/webappapis/scripting/event-loops/* SET TIMEOUT: html/webappapis/scripting/event-loops/*
SET TIMEOUT: html/webappapis/scripting/events/event-handler-processing-algorithm-error/* SET TIMEOUT: html/webappapis/scripting/events/event-handler-processing-algorithm-error/*
......
...@@ -36,6 +36,7 @@ ...@@ -36,6 +36,7 @@
#include "third_party/blink/renderer/bindings/core/v8/script_value.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/bindings/core/v8/source_location.h" #include "third_party/blink/renderer/bindings/core/v8/source_location.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h" #include "third_party/blink/renderer/bindings/core/v8/v8_binding_for_core.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h" #include "third_party/blink/renderer/bindings/core/v8/v8_gc_controller.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h" #include "third_party/blink/renderer/bindings/core/v8/v8_script_runner.h"
#include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h" #include "third_party/blink/renderer/bindings/core/v8/worker_or_worklet_script_controller.h"
...@@ -53,9 +54,8 @@ namespace blink { ...@@ -53,9 +54,8 @@ namespace blink {
ScheduledAction* ScheduledAction::Create(ScriptState* script_state, ScheduledAction* ScheduledAction::Create(ScriptState* script_state,
ExecutionContext* target, ExecutionContext* target,
const ScriptValue& handler, V8Function* handler,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
DCHECK(handler.IsFunction());
if (!script_state->World().IsWorkerWorld()) { if (!script_state->World().IsWorkerWorld()) {
if (!BindingSecurity::ShouldAllowAccessToFrame( if (!BindingSecurity::ShouldAllowAccessToFrame(
EnteredDOMWindow(script_state->GetIsolate()), EnteredDOMWindow(script_state->GetIsolate()),
...@@ -85,12 +85,14 @@ ScheduledAction* ScheduledAction::Create(ScriptState* script_state, ...@@ -85,12 +85,14 @@ ScheduledAction* ScheduledAction::Create(ScriptState* script_state,
ScheduledAction::~ScheduledAction() { ScheduledAction::~ScheduledAction() {
// Verify that owning DOMTimer has eagerly disposed. // Verify that owning DOMTimer has eagerly disposed.
DCHECK(info_.IsEmpty()); DCHECK(arguments_.IsEmpty());
DCHECK(!function_);
DCHECK(!script_state_);
} }
void ScheduledAction::Dispose() { void ScheduledAction::Dispose() {
code_ = String(); code_ = String();
info_.Clear(); arguments_.clear();
function_.Clear(); function_.Clear();
script_state_->Reset(); script_state_->Reset();
script_state_.Clear(); script_state_.Clear();
...@@ -98,6 +100,7 @@ void ScheduledAction::Dispose() { ...@@ -98,6 +100,7 @@ void ScheduledAction::Dispose() {
void ScheduledAction::Trace(blink::Visitor* visitor) { void ScheduledAction::Trace(blink::Visitor* visitor) {
visitor->Trace(script_state_); visitor->Trace(script_state_);
visitor->Trace(function_);
} }
void ScheduledAction::Execute(ExecutionContext* context) { void ScheduledAction::Execute(ExecutionContext* context) {
...@@ -128,15 +131,11 @@ void ScheduledAction::Execute(ExecutionContext* context) { ...@@ -128,15 +131,11 @@ void ScheduledAction::Execute(ExecutionContext* context) {
} }
ScheduledAction::ScheduledAction(ScriptState* script_state, ScheduledAction::ScheduledAction(ScriptState* script_state,
const ScriptValue& function, V8Function* function,
const Vector<ScriptValue>& arguments) const Vector<ScriptValue>& arguments)
: ScheduledAction(script_state) { : ScheduledAction(script_state) {
DCHECK(function.IsFunction()); function_ = function;
function_.Set(script_state->GetIsolate(), arguments_ = arguments;
v8::Local<v8::Function>::Cast(function.V8Value()));
info_.ReserveCapacity(arguments.size());
for (const ScriptValue& argument : arguments)
info_.Append(argument.V8Value());
} }
ScheduledAction::ScheduledAction(ScriptState* script_state, const String& code) ScheduledAction::ScheduledAction(ScriptState* script_state, const String& code)
...@@ -145,29 +144,34 @@ ScheduledAction::ScheduledAction(ScriptState* script_state, const String& code) ...@@ -145,29 +144,34 @@ ScheduledAction::ScheduledAction(ScriptState* script_state, const String& code)
} }
ScheduledAction::ScheduledAction(ScriptState* script_state) ScheduledAction::ScheduledAction(ScriptState* script_state)
: script_state_(ScriptStateProtectingContext::Create(script_state)), : script_state_(ScriptStateProtectingContext::Create(script_state)) {}
info_(script_state->GetIsolate()) {}
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
void ScheduledAction::Execute(LocalFrame* frame) { void ScheduledAction::Execute(LocalFrame* frame) {
DCHECK(script_state_->ContextIsValid()); DCHECK(script_state_->ContextIsValid());
TRACE_EVENT0("v8", "ScheduledAction::execute"); TRACE_EVENT0("v8", "ScheduledAction::execute");
if (!function_.IsEmpty()) { if (function_) {
DVLOG(1) << "ScheduledAction::execute " << this << ": have function"; DVLOG(1) << "ScheduledAction::execute " << this << ": have function";
v8::Local<v8::Function> function =
function_.NewLocal(script_state_->GetIsolate()); // The method context is set in
ScriptState* script_state_for_func = // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
ScriptState::From(function->CreationContext()); // as "the object on which the method for which the algorithm is running is
if (!script_state_for_func->ContextIsValid()) { // implemented (a Window or WorkerGlobalScope object)."
DVLOG(1) << "ScheduledAction::execute " << this ScriptWrappable* method_context =
<< ": function's context is empty"; ToScriptWrappable(script_state_->GetContext()->Global());
return;
} // 7.2. Run the appropriate set of steps from the following list:
Vector<v8::Local<v8::Value>> info; //
CreateLocalHandlesForArgs(&info); // If the first method argument is a Function:
V8ScriptRunner::CallFunction( //
function, frame->GetDocument(), script_state_->GetContext()->Global(), // Invoke the Function. Use the third and subsequent method
info.size(), info.data(), script_state_->GetIsolate()); // arguments (if any) as the arguments for invoking the Function.
// Use method context proxy as the callback this value.
//
// InvokeAndReportException() is responsible for converting the method
// context to the method context proxy, if needed.
function_->InvokeAndReportException(method_context, arguments_);
} else { } else {
DVLOG(1) << "ScheduledAction::execute " << this DVLOG(1) << "ScheduledAction::execute " << this
<< ": executing from source"; << ": executing from source";
...@@ -186,6 +190,7 @@ void ScheduledAction::Execute(LocalFrame* frame) { ...@@ -186,6 +190,7 @@ void ScheduledAction::Execute(LocalFrame* frame) {
// released it. // released it.
} }
// https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#timers
void ScheduledAction::Execute(WorkerGlobalScope* worker) { void ScheduledAction::Execute(WorkerGlobalScope* worker) {
DCHECK(worker->GetThread()->IsCurrentThread()); DCHECK(worker->GetThread()->IsCurrentThread());
...@@ -194,22 +199,25 @@ void ScheduledAction::Execute(WorkerGlobalScope* worker) { ...@@ -194,22 +199,25 @@ void ScheduledAction::Execute(WorkerGlobalScope* worker) {
return; return;
} }
if (!function_.IsEmpty()) { if (function_) {
ScriptState::Scope scope(script_state_->Get()); // The method context is set in
v8::Local<v8::Function> function = // https://html.spec.whatwg.org/multipage/timers-and-user-prompts.html#dom-settimeout
function_.NewLocal(script_state_->GetIsolate()); // as "the object on which the method for which the algorithm is running is
ScriptState* script_state_for_func = // implemented (a Window or WorkerGlobalScope object)."
ScriptState::From(function->CreationContext()); ScriptWrappable* method_context =
if (!script_state_for_func->ContextIsValid()) { ToScriptWrappable(script_state_->GetContext()->Global());
DVLOG(1) << "ScheduledAction::execute " << this
<< ": function's context is empty"; // 7.2. Run the appropriate set of steps from the following list:
return; //
} // If the first method argument is a Function:
Vector<v8::Local<v8::Value>> info; //
CreateLocalHandlesForArgs(&info); // Invoke the Function. Use the third and subsequent method
V8ScriptRunner::CallFunction( // arguments (if any) as the arguments for invoking the Function.
function, worker, script_state_->GetContext()->Global(), info.size(), // Use method context proxy as the callback this value.
info.data(), script_state_->GetIsolate()); //
// InvokeAndReportException() is responsible for converting the method
// context to the method context proxy, if needed.
function_->InvokeAndReportException(method_context, arguments_);
} else { } else {
// We're using |kSharableCrossOrigin| to keep the existing behavior, but // We're using |kSharableCrossOrigin| to keep the existing behavior, but
// this causes failures on // this causes failures on
...@@ -222,12 +230,4 @@ void ScheduledAction::Execute(WorkerGlobalScope* worker) { ...@@ -222,12 +230,4 @@ void ScheduledAction::Execute(WorkerGlobalScope* worker) {
} }
} }
void ScheduledAction::CreateLocalHandlesForArgs(
Vector<v8::Local<v8::Value>>* handles) {
wtf_size_t handle_count = SafeCast<wtf_size_t>(info_.Size());
handles->ReserveCapacity(handle_count);
for (wtf_size_t i = 0; i < handle_count; ++i)
handles->push_back(info_.Get(i));
}
} // namespace blink } // namespace blink
...@@ -31,29 +31,28 @@ ...@@ -31,29 +31,28 @@
#ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCHEDULED_ACTION_H_ #ifndef THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCHEDULED_ACTION_H_
#define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCHEDULED_ACTION_H_ #define THIRD_PARTY_BLINK_RENDERER_BINDINGS_CORE_V8_SCHEDULED_ACTION_H_
#include "third_party/blink/renderer/bindings/core/v8/v8_persistent_value_vector.h" #include "third_party/blink/renderer/bindings/core/v8/script_value.h"
#include "third_party/blink/renderer/platform/bindings/scoped_persistent.h" #include "third_party/blink/renderer/bindings/core/v8/v8_function.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h" #include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/forward.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "v8/include/v8.h"
namespace blink { namespace blink {
class LocalFrame;
class ExecutionContext; class ExecutionContext;
class ScriptValue; class LocalFrame;
class WorkerGlobalScope; class WorkerGlobalScope;
class ScheduledAction final class ScheduledAction final : public GarbageCollectedFinalized<ScheduledAction>,
: public GarbageCollectedFinalized<ScheduledAction> { public NameClient {
WTF_MAKE_NONCOPYABLE(ScheduledAction); WTF_MAKE_NONCOPYABLE(ScheduledAction);
public: public:
static ScheduledAction* Create(ScriptState*, static ScheduledAction* Create(ScriptState*,
ExecutionContext* target, ExecutionContext* target,
const ScriptValue& handler, V8Function* handler,
const Vector<ScriptValue>& arguments); const Vector<ScriptValue>& arguments);
static ScheduledAction* Create(ScriptState*, static ScheduledAction* Create(ScriptState*,
ExecutionContext* target, ExecutionContext* target,
...@@ -63,12 +62,13 @@ class ScheduledAction final ...@@ -63,12 +62,13 @@ class ScheduledAction final
void Dispose(); void Dispose();
void Trace(blink::Visitor*); void Trace(blink::Visitor*);
const char* NameInHeapSnapshot() const override { return "ScheduledAction"; }
void Execute(ExecutionContext*); void Execute(ExecutionContext*);
private: private:
ScheduledAction(ScriptState*, ScheduledAction(ScriptState*,
const ScriptValue& handler, V8Function* handler,
const Vector<ScriptValue>& arguments); const Vector<ScriptValue>& arguments);
ScheduledAction(ScriptState*, const String& handler); ScheduledAction(ScriptState*, const String& handler);
...@@ -77,11 +77,10 @@ class ScheduledAction final ...@@ -77,11 +77,10 @@ class ScheduledAction final
void Execute(LocalFrame*); void Execute(LocalFrame*);
void Execute(WorkerGlobalScope*); void Execute(WorkerGlobalScope*);
void CreateLocalHandlesForArgs(Vector<v8::Local<v8::Value>>* handles);
Member<ScriptStateProtectingContext> script_state_; Member<ScriptStateProtectingContext> script_state_;
ScopedPersistent<v8::Function> function_; TraceWrapperMember<V8Function> function_;
V8PersistentValueVector<v8::Value> info_; Vector<ScriptValue> arguments_;
String code_; String code_;
}; };
......
...@@ -174,6 +174,9 @@ void DOMTimer::Fired() { ...@@ -174,6 +174,9 @@ void DOMTimer::Fired() {
action->Execute(context); action->Execute(context);
// Eagerly clear out |action|'s resources.
action->Dispose();
// ExecutionContext might be already gone when we executed action->execute(). // ExecutionContext might be already gone when we executed action->execute().
ExecutionContext* execution_context = GetExecutionContext(); ExecutionContext* execution_context = GetExecutionContext();
if (!execution_context) if (!execution_context)
...@@ -182,8 +185,6 @@ void DOMTimer::Fired() { ...@@ -182,8 +185,6 @@ void DOMTimer::Fired() {
execution_context->Timers()->SetTimerNestingLevel(0); execution_context->Timers()->SetTimerNestingLevel(0);
// Eagerly unregister as ExecutionContext observer. // Eagerly unregister as ExecutionContext observer.
ClearContext(); ClearContext();
// Eagerly clear out |action|'s resources.
action->Dispose();
} }
scoped_refptr<base::SingleThreadTaskRunner> DOMTimer::TimerTaskRunner() const { scoped_refptr<base::SingleThreadTaskRunner> DOMTimer::TimerTaskRunner() const {
......
...@@ -32,6 +32,8 @@ ...@@ -32,6 +32,8 @@
#include "third_party/blink/renderer/core/core_export.h" #include "third_party/blink/renderer/core/core_export.h"
#include "third_party/blink/renderer/core/dom/user_gesture_indicator.h" #include "third_party/blink/renderer/core/dom/user_gesture_indicator.h"
#include "third_party/blink/renderer/core/frame/pausable_timer.h" #include "third_party/blink/renderer/core/frame/pausable_timer.h"
#include "third_party/blink/renderer/platform/bindings/name_client.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
namespace blink { namespace blink {
...@@ -39,7 +41,8 @@ namespace blink { ...@@ -39,7 +41,8 @@ namespace blink {
class ExecutionContext; class ExecutionContext;
class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>, class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>,
public PausableTimer { public PausableTimer,
public NameClient {
USING_GARBAGE_COLLECTED_MIXIN(DOMTimer); USING_GARBAGE_COLLECTED_MIXIN(DOMTimer);
public: public:
...@@ -62,6 +65,7 @@ class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>, ...@@ -62,6 +65,7 @@ class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>,
// already have been finalized & must not be accessed. // already have been finalized & must not be accessed.
EAGERLY_FINALIZE(); EAGERLY_FINALIZE();
void Trace(blink::Visitor*) override; void Trace(blink::Visitor*) override;
const char* NameInHeapSnapshot() const override { return "DOMTimer"; }
void Stop() override; void Stop() override;
...@@ -87,7 +91,7 @@ class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>, ...@@ -87,7 +91,7 @@ class CORE_EXPORT DOMTimer final : public GarbageCollectedFinalized<DOMTimer>,
int timeout_id_; int timeout_id_;
int nesting_level_; int nesting_level_;
Member<ScheduledAction> action_; TraceWrapperMember<ScheduledAction> action_;
scoped_refptr<UserGestureToken> user_gesture_token_; scoped_refptr<UserGestureToken> user_gesture_token_;
}; };
......
...@@ -9,6 +9,7 @@ ...@@ -9,6 +9,7 @@
#include "base/macros.h" #include "base/macros.h"
#include "base/single_thread_task_runner.h" #include "base/single_thread_task_runner.h"
#include "third_party/blink/renderer/platform/bindings/trace_wrapper_member.h"
#include "third_party/blink/renderer/platform/heap/handle.h" #include "third_party/blink/renderer/platform/heap/handle.h"
#include "third_party/blink/renderer/platform/wtf/time.h" #include "third_party/blink/renderer/platform/wtf/time.h"
...@@ -59,7 +60,7 @@ class DOMTimerCoordinator { ...@@ -59,7 +60,7 @@ class DOMTimerCoordinator {
private: private:
int NextID(); int NextID();
using TimeoutMap = HeapHashMap<int, Member<DOMTimer>>; using TimeoutMap = HeapHashMap<int, TraceWrapperMember<DOMTimer>>;
TimeoutMap timers_; TimeoutMap timers_;
int circular_sequential_id_; int circular_sequential_id_;
......
...@@ -84,7 +84,7 @@ static bool IsAllowed(ScriptState* script_state, ...@@ -84,7 +84,7 @@ static bool IsAllowed(ScriptState* script_state,
int setTimeout(ScriptState* script_state, int setTimeout(ScriptState* script_state,
EventTarget& event_target, EventTarget& event_target,
const ScriptValue& handler, V8Function* handler,
int timeout, int timeout,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
ExecutionContext* execution_context = event_target.GetExecutionContext(); ExecutionContext* execution_context = event_target.GetExecutionContext();
...@@ -144,7 +144,7 @@ int setTimeoutFromString(ScriptState* script_state, ...@@ -144,7 +144,7 @@ int setTimeoutFromString(ScriptState* script_state,
int setInterval(ScriptState* script_state, int setInterval(ScriptState* script_state,
EventTarget& event_target, EventTarget& event_target,
const ScriptValue& handler, V8Function* handler,
int timeout, int timeout,
const Vector<ScriptValue>& arguments) { const Vector<ScriptValue>& arguments) {
ExecutionContext* execution_context = event_target.GetExecutionContext(); ExecutionContext* execution_context = event_target.GetExecutionContext();
......
...@@ -43,11 +43,12 @@ class ExceptionState; ...@@ -43,11 +43,12 @@ class ExceptionState;
class ScriptState; class ScriptState;
class ScriptValue; class ScriptValue;
class StringOrTrustedScript; class StringOrTrustedScript;
class V8Function;
namespace DOMWindowTimers { namespace DOMWindowTimers {
int setTimeout(ScriptState*, int setTimeout(ScriptState*,
EventTarget&, EventTarget&,
const ScriptValue& handler, V8Function* handler,
int timeout, int timeout,
const Vector<ScriptValue>& arguments); const Vector<ScriptValue>& arguments);
int setTimeout(ScriptState*, int setTimeout(ScriptState*,
...@@ -63,7 +64,7 @@ int setTimeoutFromString(ScriptState*, ...@@ -63,7 +64,7 @@ int setTimeoutFromString(ScriptState*,
const Vector<ScriptValue>&); const Vector<ScriptValue>&);
int setInterval(ScriptState*, int setInterval(ScriptState*,
EventTarget&, EventTarget&,
const ScriptValue& handler, V8Function* handler,
int timeout, int timeout,
const Vector<ScriptValue>&); const Vector<ScriptValue>&);
int setInterval(ScriptState*, int setInterval(ScriptState*,
......
...@@ -34,13 +34,14 @@ ...@@ -34,13 +34,14 @@
NoInterfaceObject, // Always used on target of 'implements' NoInterfaceObject, // Always used on target of 'implements'
Exposed=(Window,Worker) Exposed=(Window,Worker)
] interface WindowTimers { ] interface WindowTimers {
// TODO(yukishiino): Use TimerHandler (or Function at least) to implement // TODO(yukishiino): Use TimerHandler to implement setTimeout and
// setTimeout and setInterval. // setInterval, when the IDL code generator supports unions of a callback
// function and a string.
// https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin // https://html.spec.whatwg.org/C/webappapis.html#windoworworkerglobalscope-mixin
[CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(CallbackFunctionTreatedAsScriptValue handler, optional long timeout = 0, any... arguments); [CallWith=ScriptState, RuntimeCallStatsCounter=WindowSetTimeout] long setTimeout(Function handler, optional long timeout = 0, any... arguments);
[CallWith=ScriptState, RaisesException] long setTimeout(ScriptString handler, optional long timeout = 0, any... arguments); [CallWith=ScriptState, RaisesException] long setTimeout(ScriptString handler, optional long timeout = 0, any... arguments);
void clearTimeout(optional long handle = 0); void clearTimeout(optional long handle = 0);
[CallWith=ScriptState] long setInterval(CallbackFunctionTreatedAsScriptValue handler, optional long timeout = 0, any... arguments); [CallWith=ScriptState] long setInterval(Function handler, optional long timeout = 0, any... arguments);
[CallWith=ScriptState, RaisesException] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments); [CallWith=ScriptState, RaisesException] long setInterval(ScriptString handler, optional long timeout = 0, any... arguments);
void clearInterval(optional long handle = 0); void clearInterval(optional long handle = 0);
}; };
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment