OLD | NEW |
---|---|
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "config.h" | 5 #include "config.h" |
6 #include "bindings/v8/ScriptPromiseResolverWithContext.h" | 6 #include "bindings/v8/ScriptPromiseResolverWithContext.h" |
7 | 7 |
8 #include "bindings/v8/V8PerIsolateData.h" | |
9 | |
8 namespace WebCore { | 10 namespace WebCore { |
9 | 11 |
12 namespace { | |
13 | |
14 // An empty function that is needed to run microtasks. | |
15 void noop(const v8::FunctionCallbackInfo<v8::Value>& info) | |
16 { | |
17 } | |
18 | |
19 v8::Handle<v8::Function> getNoopFunction(v8::Isolate* isolate) | |
20 { | |
21 static int key; | |
22 V8PerIsolateData* data = V8PerIsolateData::from(isolate); | |
23 v8::Handle<v8::FunctionTemplate> functionDescriptor = data->existingDOMTempl ate(&key); | |
24 if (functionDescriptor.IsEmpty()) { | |
25 functionDescriptor = v8::FunctionTemplate::New(isolate, noop); | |
26 data->setDOMTemplate(&key, functionDescriptor); | |
27 } | |
28 return functionDescriptor->GetFunction(); | |
29 } | |
30 | |
31 } // namespace | |
32 | |
10 ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(NewScriptStat e* scriptState) | 33 ScriptPromiseResolverWithContext::ScriptPromiseResolverWithContext(NewScriptStat e* scriptState) |
11 : ActiveDOMObject(scriptState->executionContext()) | 34 : ActiveDOMObject(scriptState->executionContext()) |
12 , m_state(Pending) | 35 , m_state(Pending) |
13 , m_scriptState(scriptState) | 36 , m_scriptState(scriptState) |
14 , m_timer(this, &ScriptPromiseResolverWithContext::resolveOrRejectImmediatel y) | 37 , m_timer(this, &ScriptPromiseResolverWithContext::onTimerFired) |
15 , m_resolver(ScriptPromiseResolver::create(m_scriptState->executionContext() )) { } | 38 , m_resolver(ScriptPromiseResolver::create(m_scriptState->executionContext() )) { } |
16 | 39 |
17 void ScriptPromiseResolverWithContext::suspend() | 40 void ScriptPromiseResolverWithContext::suspend() |
18 { | 41 { |
19 m_timer.stop(); | 42 m_timer.stop(); |
20 } | 43 } |
21 | 44 |
22 void ScriptPromiseResolverWithContext::resume() | 45 void ScriptPromiseResolverWithContext::resume() |
23 { | 46 { |
24 if (m_state == Resolving || m_state == Rejecting) | 47 if (m_state == Resolving || m_state == Rejecting) |
25 m_timer.startOneShot(0, FROM_HERE); | 48 m_timer.startOneShot(0, FROM_HERE); |
26 } | 49 } |
27 | 50 |
28 void ScriptPromiseResolverWithContext::stop() | 51 void ScriptPromiseResolverWithContext::stop() |
29 { | 52 { |
30 m_timer.stop(); | 53 m_timer.stop(); |
31 clear(); | 54 clear(); |
32 } | 55 } |
33 | 56 |
34 void ScriptPromiseResolverWithContext::resolveOrRejectImmediately(Timer<ScriptPr omiseResolverWithContext>*) | 57 void ScriptPromiseResolverWithContext::onTimerFired(Timer<ScriptPromiseResolverW ithContext>*) |
58 { | |
59 RefPtr<ScriptPromiseResolverWithContext> protect(this); | |
60 NewScriptState::Scope scope(m_scriptState.get()); | |
61 v8::Isolate* isolate = m_scriptState->isolate(); | |
62 resolveOrRejectImmediately(); | |
63 | |
64 // Call an empty function to run microtasks. | |
65 // Create one-element array to make MSVC happy (C2466). | |
66 v8::Handle<v8::Value> args[1]; | |
67 getNoopFunction(isolate)->Call(v8::Undefined(isolate), 0, args); | |
yhirano
2014/04/15 08:45:06
I'm wondering if calling v8::V8::RunMicrotasks her
yhirano
2014/04/15 10:33:40
Calling an empty function violates some assertions
| |
68 } | |
69 | |
70 void ScriptPromiseResolverWithContext::resolveOrRejectImmediately() | |
35 { | 71 { |
36 ASSERT(!executionContext()->activeDOMObjectsAreStopped()); | 72 ASSERT(!executionContext()->activeDOMObjectsAreStopped()); |
37 ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); | 73 ASSERT(!executionContext()->activeDOMObjectsAreSuspended()); |
38 if (m_state == Resolving) { | 74 if (m_state == Resolving) { |
39 NewScriptState::Scope scope(m_scriptState.get()); | |
40 m_resolver->resolve(m_value.newLocal(m_scriptState->isolate())); | 75 m_resolver->resolve(m_value.newLocal(m_scriptState->isolate())); |
41 } else { | 76 } else { |
42 ASSERT(m_state == Rejecting); | 77 ASSERT(m_state == Rejecting); |
43 NewScriptState::Scope scope(m_scriptState.get()); | |
44 m_resolver->reject(m_value.newLocal(m_scriptState->isolate())); | 78 m_resolver->reject(m_value.newLocal(m_scriptState->isolate())); |
45 } | 79 } |
46 m_state = ResolvedOrRejected; | 80 m_state = ResolvedOrRejected; |
47 clear(); | 81 clear(); |
82 | |
83 // ref() was called in resolveOrRejected. | |
84 deref(); | |
48 } | 85 } |
49 | 86 |
50 void ScriptPromiseResolverWithContext::clear() | 87 void ScriptPromiseResolverWithContext::clear() |
51 { | 88 { |
52 m_resolver.clear(); | 89 m_resolver.clear(); |
53 m_value.clear(); | 90 m_value.clear(); |
54 m_scriptState.clear(); | 91 m_scriptState.clear(); |
55 } | 92 } |
56 | 93 |
57 } // namespace WebCore | 94 } // namespace WebCore |
OLD | NEW |