Chromium Code Reviews| 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 |