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 "bindings/core/v8/ScriptPromisePropertyBase.h" | 5 #include "bindings/core/v8/ScriptPromisePropertyBase.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include "bindings/core/v8/ScopedPersistent.h" | 8 #include "bindings/core/v8/ScopedPersistent.h" |
| 9 #include "bindings/core/v8/ScriptState.h" | 9 #include "bindings/core/v8/ScriptState.h" |
| 10 #include "bindings/core/v8/V8Binding.h" | 10 #include "bindings/core/v8/V8Binding.h" |
| (...skipping 22 matching lines...) Expand all Loading... | |
| 33 v8::HandleScope handleScope(m_isolate); | 33 v8::HandleScope handleScope(m_isolate); |
| 34 v8::Local<v8::Context> context = toV8Context(getExecutionContext(), world); | 34 v8::Local<v8::Context> context = toV8Context(getExecutionContext(), world); |
| 35 if (context.IsEmpty()) | 35 if (context.IsEmpty()) |
| 36 return ScriptPromise(); | 36 return ScriptPromise(); |
| 37 ScriptState* scriptState = ScriptState::from(context); | 37 ScriptState* scriptState = ScriptState::from(context); |
| 38 ScriptState::Scope scope(scriptState); | 38 ScriptState::Scope scope(scriptState); |
| 39 | 39 |
| 40 v8::Local<v8::Object> wrapper = ensureHolderWrapper(scriptState); | 40 v8::Local<v8::Object> wrapper = ensureHolderWrapper(scriptState); |
| 41 DCHECK(wrapper->CreationContext() == context); | 41 DCHECK(wrapper->CreationContext() == context); |
| 42 | 42 |
| 43 v8::Local<v8::Value> cachedPromise = | 43 v8::Local<v8::Value> cachedPromise = promiseSymbol().getOrUndefined(wrapper); |
| 44 V8HiddenValue::getHiddenValue(scriptState, wrapper, promiseName()); | 44 if (!cachedPromise->IsUndefined() && cachedPromise->IsPromise()) |
| 45 if (!cachedPromise.IsEmpty() && cachedPromise->IsPromise()) | |
| 46 return ScriptPromise(scriptState, cachedPromise); | 45 return ScriptPromise(scriptState, cachedPromise); |
| 47 | 46 |
| 48 // Create and cache the Promise | 47 // Create and cache the Promise |
| 49 v8::Local<v8::Promise::Resolver> resolver; | 48 v8::Local<v8::Promise::Resolver> resolver; |
| 50 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) | 49 if (!v8::Promise::Resolver::New(context).ToLocal(&resolver)) |
| 51 return ScriptPromise(); | 50 return ScriptPromise(); |
| 52 v8::Local<v8::Promise> promise = resolver->GetPromise(); | 51 v8::Local<v8::Promise> promise = resolver->GetPromise(); |
| 53 V8HiddenValue::setHiddenValue(scriptState, wrapper, promiseName(), promise); | 52 promiseSymbol().set(wrapper, promise); |
| 54 | 53 |
| 55 switch (m_state) { | 54 switch (m_state) { |
| 56 case Pending: | 55 case Pending: |
| 57 // Cache the resolver too | 56 // Cache the resolver too |
| 58 V8HiddenValue::setHiddenValue(scriptState, wrapper, resolverName(), | 57 resolverSymbol().set(wrapper, resolver); |
| 59 resolver); | |
| 60 break; | 58 break; |
| 61 case Resolved: | 59 case Resolved: |
| 62 case Rejected: | 60 case Rejected: |
| 63 resolveOrRejectInternal(resolver); | 61 resolveOrRejectInternal(resolver); |
| 64 break; | 62 break; |
| 65 } | 63 } |
| 66 | 64 |
| 67 return ScriptPromise(scriptState, promise); | 65 return ScriptPromise(scriptState, promise); |
| 68 } | 66 } |
| 69 | 67 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 83 // wrapper has died. | 81 // wrapper has died. |
| 84 // Since v8 GC can run during the iteration and clear the reference, | 82 // Since v8 GC can run during the iteration and clear the reference, |
| 85 // we can't move this check out of the loop. | 83 // we can't move this check out of the loop. |
| 86 m_wrappers.erase(i); | 84 m_wrappers.erase(i); |
| 87 continue; | 85 continue; |
| 88 } | 86 } |
| 89 v8::Local<v8::Object> wrapper = persistent->newLocal(m_isolate); | 87 v8::Local<v8::Object> wrapper = persistent->newLocal(m_isolate); |
| 90 ScriptState* scriptState = ScriptState::from(wrapper->CreationContext()); | 88 ScriptState* scriptState = ScriptState::from(wrapper->CreationContext()); |
| 91 ScriptState::Scope scope(scriptState); | 89 ScriptState::Scope scope(scriptState); |
| 92 | 90 |
| 91 V8PrivateProperty::Symbol symbol = resolverSymbol(); | |
| 92 DCHECK(symbol.hasValue(wrapper)); | |
| 93 v8::Local<v8::Promise::Resolver> resolver = | 93 v8::Local<v8::Promise::Resolver> resolver = |
| 94 V8HiddenValue::getHiddenValue(scriptState, wrapper, resolverName()) | 94 symbol.getOrUndefined(wrapper).As<v8::Promise::Resolver>(); |
| 95 .As<v8::Promise::Resolver>(); | |
| 96 DCHECK(!resolver.IsEmpty()); | |
| 97 | 95 |
| 98 V8HiddenValue::deleteHiddenValue(scriptState, wrapper, resolverName()); | 96 symbol.deleteProperty(wrapper); |
| 99 resolveOrRejectInternal(resolver); | 97 resolveOrRejectInternal(resolver); |
| 100 ++i; | 98 ++i; |
| 101 } | 99 } |
| 102 } | 100 } |
| 103 | 101 |
| 104 void ScriptPromisePropertyBase::resetBase() { | 102 void ScriptPromisePropertyBase::resetBase() { |
| 105 checkThis(); | 103 checkThis(); |
| 106 clearWrappers(); | 104 clearWrappers(); |
| 107 m_state = Pending; | 105 m_state = Pending; |
| 108 } | 106 } |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 156 } | 154 } |
| 157 | 155 |
| 158 void ScriptPromisePropertyBase::clearWrappers() { | 156 void ScriptPromisePropertyBase::clearWrappers() { |
| 159 checkThis(); | 157 checkThis(); |
| 160 checkWrappers(); | 158 checkWrappers(); |
| 161 v8::HandleScope handleScope(m_isolate); | 159 v8::HandleScope handleScope(m_isolate); |
| 162 for (WeakPersistentSet::iterator i = m_wrappers.begin(); | 160 for (WeakPersistentSet::iterator i = m_wrappers.begin(); |
| 163 i != m_wrappers.end(); ++i) { | 161 i != m_wrappers.end(); ++i) { |
| 164 v8::Local<v8::Object> wrapper = (*i)->newLocal(m_isolate); | 162 v8::Local<v8::Object> wrapper = (*i)->newLocal(m_isolate); |
| 165 if (!wrapper.IsEmpty()) { | 163 if (!wrapper.IsEmpty()) { |
| 166 ScriptState* scriptState = ScriptState::from(wrapper->CreationContext()); | 164 resolverSymbol().deleteProperty(wrapper); |
| 167 V8HiddenValue::deleteHiddenValue(scriptState, wrapper, resolverName()); | 165 // TODO(peria): Use deleteProperty() if http://crbug.com/v8/6227 is fixed. |
| 168 V8HiddenValue::deleteHiddenValue(scriptState, wrapper, promiseName()); | 166 promiseSymbol().set(wrapper, v8::Undefined(m_isolate)); |
|
peria
2017/04/07 09:43:37
v8::Object::DeleteProperty() seems to have a bug i
| |
| 169 } | 167 } |
| 170 } | 168 } |
| 171 m_wrappers.clear(); | 169 m_wrappers.clear(); |
| 172 } | 170 } |
| 173 | 171 |
| 174 void ScriptPromisePropertyBase::checkThis() { | 172 void ScriptPromisePropertyBase::checkThis() { |
| 175 RELEASE_ASSERT(this); | 173 RELEASE_ASSERT(this); |
| 176 } | 174 } |
| 177 | 175 |
| 178 void ScriptPromisePropertyBase::checkWrappers() { | 176 void ScriptPromisePropertyBase::checkWrappers() { |
| 179 for (WeakPersistentSet::iterator i = m_wrappers.begin(); | 177 for (WeakPersistentSet::iterator i = m_wrappers.begin(); |
| 180 i != m_wrappers.end(); ++i) { | 178 i != m_wrappers.end(); ++i) { |
| 181 RELEASE_ASSERT(*i); | 179 RELEASE_ASSERT(*i); |
| 182 } | 180 } |
| 183 } | 181 } |
| 184 | 182 |
| 185 v8::Local<v8::String> ScriptPromisePropertyBase::promiseName() { | 183 V8PrivateProperty::Symbol ScriptPromisePropertyBase::promiseSymbol() { |
| 186 switch (m_name) { | 184 switch (m_name) { |
| 187 #define P(Name) \ | 185 #define P(Interface, Name) \ |
| 188 case Name: \ | 186 case Name: \ |
| 189 return V8HiddenValue::Name##Promise(m_isolate); | 187 return V8PrivateProperty::V8_PRIVATE_PROPERTY_GETTER_NAME( \ |
| 188 Interface, Name##Promise)(m_isolate); | |
| 190 | 189 |
| 191 SCRIPT_PROMISE_PROPERTIES(P) | 190 SCRIPT_PROMISE_PROPERTIES(P) |
| 192 | 191 |
| 193 #undef P | 192 #undef P |
| 194 } | 193 } |
| 195 ASSERT_NOT_REACHED(); | 194 NOTREACHED(); |
| 196 return v8::Local<v8::String>(); | 195 return V8PrivateProperty::getSymbol(m_isolate, "noPromise"); |
| 197 } | 196 } |
| 198 | 197 |
| 199 v8::Local<v8::String> ScriptPromisePropertyBase::resolverName() { | 198 V8PrivateProperty::Symbol ScriptPromisePropertyBase::resolverSymbol() { |
| 200 switch (m_name) { | 199 switch (m_name) { |
| 201 #define P(Name) \ | 200 #define P(Interface, Name) \ |
| 202 case Name: \ | 201 case Name: \ |
| 203 return V8HiddenValue::Name##Resolver(m_isolate); | 202 return V8PrivateProperty::V8_PRIVATE_PROPERTY_GETTER_NAME( \ |
| 203 Interface, Name##Resolver)(m_isolate); | |
| 204 | 204 |
| 205 SCRIPT_PROMISE_PROPERTIES(P) | 205 SCRIPT_PROMISE_PROPERTIES(P) |
| 206 | 206 |
| 207 #undef P | 207 #undef P |
| 208 } | 208 } |
| 209 ASSERT_NOT_REACHED(); | 209 NOTREACHED(); |
| 210 return v8::Local<v8::String>(); | 210 return V8PrivateProperty::getSymbol(m_isolate, "noResolver"); |
| 211 } | 211 } |
| 212 | 212 |
| 213 DEFINE_TRACE(ScriptPromisePropertyBase) { | 213 DEFINE_TRACE(ScriptPromisePropertyBase) { |
| 214 ContextClient::trace(visitor); | 214 ContextClient::trace(visitor); |
| 215 } | 215 } |
| 216 | 216 |
| 217 } // namespace blink | 217 } // namespace blink |
| OLD | NEW |