| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2013 Google Inc. All rights reserved. | 2 * Copyright (C) 2013 Google Inc. All rights reserved. |
| 3 * | 3 * |
| 4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
| 5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
| 6 * met: | 6 * met: |
| 7 * | 7 * |
| 8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
| 9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
| 10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
| (...skipping 26 matching lines...) Expand all Loading... |
| 37 #include "bindings/v8/ScriptState.h" | 37 #include "bindings/v8/ScriptState.h" |
| 38 #include "bindings/v8/V8Binding.h" | 38 #include "bindings/v8/V8Binding.h" |
| 39 #include "bindings/v8/V8HiddenValue.h" | 39 #include "bindings/v8/V8HiddenValue.h" |
| 40 #include "bindings/v8/V8PerIsolateData.h" | 40 #include "bindings/v8/V8PerIsolateData.h" |
| 41 #include "bindings/v8/V8ScriptRunner.h" | 41 #include "bindings/v8/V8ScriptRunner.h" |
| 42 #include "bindings/v8/WrapperTypeInfo.h" | 42 #include "bindings/v8/WrapperTypeInfo.h" |
| 43 #include "core/dom/Document.h" | 43 #include "core/dom/Document.h" |
| 44 #include "core/dom/ExecutionContextTask.h" | 44 #include "core/dom/ExecutionContextTask.h" |
| 45 #include "core/frame/DOMWindow.h" | 45 #include "core/frame/DOMWindow.h" |
| 46 #include "core/frame/UseCounter.h" | 46 #include "core/frame/UseCounter.h" |
| 47 #include "core/inspector/InspectorPromiseInstrumentation.h" | |
| 48 #include "core/workers/WorkerGlobalScope.h" | 47 #include "core/workers/WorkerGlobalScope.h" |
| 49 #include "platform/Task.h" | 48 #include "platform/Task.h" |
| 50 #include "wtf/Deque.h" | 49 #include "wtf/Deque.h" |
| 51 #include "wtf/Functional.h" | 50 #include "wtf/Functional.h" |
| 52 #include "wtf/Noncopyable.h" | 51 #include "wtf/Noncopyable.h" |
| 53 #include "wtf/PassOwnPtr.h" | 52 #include "wtf/PassOwnPtr.h" |
| 54 #include <v8.h> | 53 #include <v8.h> |
| 55 | 54 |
| 56 #define TONATIVE_VOID_EMPTY(type, var, value) \ | 55 #define TONATIVE_VOID_EMPTY(type, var, value) \ |
| 57 type var; \ | 56 type var; \ |
| (...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 201 | 200 |
| 202 // Set a |promise|'s state and result that correspond to the state. | 201 // Set a |promise|'s state and result that correspond to the state. |
| 203 // |promise| must be a Promise instance. | 202 // |promise| must be a Promise instance. |
| 204 void setStateForPromise(v8::Handle<v8::Object> promise, V8PromiseCustom::Promise
State state, v8::Handle<v8::Value> value, v8::Isolate* isolate) | 203 void setStateForPromise(v8::Handle<v8::Object> promise, V8PromiseCustom::Promise
State state, v8::Handle<v8::Value> value, v8::Isolate* isolate) |
| 205 { | 204 { |
| 206 ASSERT(!value.IsEmpty()); | 205 ASSERT(!value.IsEmpty()); |
| 207 ASSERT(state == V8PromiseCustom::Pending || state == V8PromiseCustom::Fulfil
led || state == V8PromiseCustom::Rejected || state == V8PromiseCustom::Following
); | 206 ASSERT(state == V8PromiseCustom::Pending || state == V8PromiseCustom::Fulfil
led || state == V8PromiseCustom::Rejected || state == V8PromiseCustom::Following
); |
| 208 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); | 207 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); |
| 209 internal->SetInternalField(V8PromiseCustom::InternalStateIndex, v8::Integer:
:New(isolate, state)); | 208 internal->SetInternalField(V8PromiseCustom::InternalStateIndex, v8::Integer:
:New(isolate, state)); |
| 210 internal->SetInternalField(V8PromiseCustom::InternalResultIndex, value); | 209 internal->SetInternalField(V8PromiseCustom::InternalResultIndex, value); |
| 211 ExecutionContext* context = currentExecutionContext(isolate); | |
| 212 if (InspectorInstrumentation::isPromiseTrackerEnabled(context)) | |
| 213 InspectorInstrumentation::didUpdatePromiseState(context, ScriptObject(Sc
riptState::current(isolate), promise), state, ScriptValue(ScriptState::current(i
solate), value)); | |
| 214 } | 210 } |
| 215 | 211 |
| 216 class TaskPerformScopeForInstrumentation { | |
| 217 public: | |
| 218 TaskPerformScopeForInstrumentation(ExecutionContext* context, ExecutionConte
xtTask* task) | |
| 219 : m_cookie(InspectorInstrumentation::willPerformPromiseTask(context, tas
k)) | |
| 220 { | |
| 221 } | |
| 222 | |
| 223 ~TaskPerformScopeForInstrumentation() | |
| 224 { | |
| 225 InspectorInstrumentation::didPerformPromiseTask(m_cookie); | |
| 226 } | |
| 227 | |
| 228 private: | |
| 229 InspectorInstrumentationCookie m_cookie; | |
| 230 }; | |
| 231 | |
| 232 class CallHandlerTask FINAL : public ExecutionContextTask { | 212 class CallHandlerTask FINAL : public ExecutionContextTask { |
| 233 public: | 213 public: |
| 234 CallHandlerTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> han
dler, v8::Handle<v8::Value> argument, V8PromiseCustom::PromiseState originatorSt
ate, v8::Isolate* isolate, ExecutionContext* context) | 214 CallHandlerTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> han
dler, v8::Handle<v8::Value> argument, V8PromiseCustom::PromiseState originatorSt
ate, v8::Isolate* isolate, ExecutionContext* context) |
| 235 : m_promise(isolate, promise) | 215 : m_promise(isolate, promise) |
| 236 , m_handler(isolate, handler) | 216 , m_handler(isolate, handler) |
| 237 , m_argument(isolate, argument) | 217 , m_argument(isolate, argument) |
| 238 , m_scriptState(ScriptState::current(isolate)) | 218 , m_scriptState(ScriptState::current(isolate)) |
| 239 { | 219 { |
| 240 ASSERT(!m_promise.isEmpty()); | 220 ASSERT(!m_promise.isEmpty()); |
| 241 ASSERT(!m_handler.isEmpty()); | 221 ASSERT(!m_handler.isEmpty()); |
| 242 ASSERT(!m_argument.isEmpty()); | 222 ASSERT(!m_argument.isEmpty()); |
| 243 InspectorInstrumentation::didPostPromiseTask(context, this, originatorSt
ate == V8PromiseCustom::Fulfilled); | |
| 244 } | 223 } |
| 245 virtual ~CallHandlerTask() { } | 224 virtual ~CallHandlerTask() { } |
| 246 | 225 |
| 247 virtual void performTask(ExecutionContext*) OVERRIDE; | 226 virtual void performTask(ExecutionContext*) OVERRIDE; |
| 248 | 227 |
| 249 private: | 228 private: |
| 250 ScopedPersistent<v8::Object> m_promise; | 229 ScopedPersistent<v8::Object> m_promise; |
| 251 ScopedPersistent<v8::Function> m_handler; | 230 ScopedPersistent<v8::Function> m_handler; |
| 252 ScopedPersistent<v8::Value> m_argument; | 231 ScopedPersistent<v8::Value> m_argument; |
| 253 RefPtr<ScriptState> m_scriptState; | 232 RefPtr<ScriptState> m_scriptState; |
| 254 }; | 233 }; |
| 255 | 234 |
| 256 void CallHandlerTask::performTask(ExecutionContext* context) | 235 void CallHandlerTask::performTask(ExecutionContext* context) |
| 257 { | 236 { |
| 258 TaskPerformScopeForInstrumentation performTaskScope(context, this); | |
| 259 | |
| 260 ASSERT(context); | 237 ASSERT(context); |
| 261 if (context->activeDOMObjectsAreStopped()) | 238 if (context->activeDOMObjectsAreStopped()) |
| 262 return; | 239 return; |
| 263 | 240 |
| 264 ScriptState::Scope scope(m_scriptState.get()); | 241 ScriptState::Scope scope(m_scriptState.get()); |
| 265 v8::Isolate* isolate = m_scriptState->isolate(); | 242 v8::Isolate* isolate = m_scriptState->isolate(); |
| 266 v8::Handle<v8::Value> info[] = { m_argument.newLocal(isolate) }; | 243 v8::Handle<v8::Value> info[] = { m_argument.newLocal(isolate) }; |
| 267 v8::TryCatch trycatch; | 244 v8::TryCatch trycatch; |
| 268 v8::Local<v8::Value> value = V8ScriptRunner::callFunction(m_handler.newLocal
(isolate), context, v8::Undefined(isolate), WTF_ARRAY_LENGTH(info), info, isolat
e); | 245 v8::Local<v8::Value> value = V8ScriptRunner::callFunction(m_handler.newLocal
(isolate), context, v8::Undefined(isolate), WTF_ARRAY_LENGTH(info), info, isolat
e); |
| 269 if (value.IsEmpty()) { | 246 if (value.IsEmpty()) { |
| 270 V8PromiseCustom::reject(m_promise.newLocal(isolate), trycatch.Exception(
), isolate); | 247 V8PromiseCustom::reject(m_promise.newLocal(isolate), trycatch.Exception(
), isolate); |
| 271 } else { | 248 } else { |
| 272 V8PromiseCustom::resolve(m_promise.newLocal(isolate), value, isolate); | 249 V8PromiseCustom::resolve(m_promise.newLocal(isolate), value, isolate); |
| 273 } | 250 } |
| 274 } | 251 } |
| 275 | 252 |
| 276 class UpdateDerivedTask FINAL : public ExecutionContextTask { | 253 class UpdateDerivedTask FINAL : public ExecutionContextTask { |
| 277 public: | 254 public: |
| 278 UpdateDerivedTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> o
nFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originat
orValueObject, v8::Isolate* isolate, ExecutionContext* context) | 255 UpdateDerivedTask(v8::Handle<v8::Object> promise, v8::Handle<v8::Function> o
nFulfilled, v8::Handle<v8::Function> onRejected, v8::Handle<v8::Object> originat
orValueObject, v8::Isolate* isolate, ExecutionContext* context) |
| 279 : m_promise(isolate, promise) | 256 : m_promise(isolate, promise) |
| 280 , m_onFulfilled(isolate, onFulfilled) | 257 , m_onFulfilled(isolate, onFulfilled) |
| 281 , m_onRejected(isolate, onRejected) | 258 , m_onRejected(isolate, onRejected) |
| 282 , m_originatorValueObject(isolate, originatorValueObject) | 259 , m_originatorValueObject(isolate, originatorValueObject) |
| 283 , m_scriptState(ScriptState::current(isolate)) | 260 , m_scriptState(ScriptState::current(isolate)) |
| 284 { | 261 { |
| 285 ASSERT(!m_promise.isEmpty()); | 262 ASSERT(!m_promise.isEmpty()); |
| 286 ASSERT(!m_originatorValueObject.isEmpty()); | 263 ASSERT(!m_originatorValueObject.isEmpty()); |
| 287 InspectorInstrumentation::didPostPromiseTask(context, this, true); | |
| 288 } | 264 } |
| 289 virtual ~UpdateDerivedTask() { } | 265 virtual ~UpdateDerivedTask() { } |
| 290 | 266 |
| 291 virtual void performTask(ExecutionContext*) OVERRIDE; | 267 virtual void performTask(ExecutionContext*) OVERRIDE; |
| 292 | 268 |
| 293 private: | 269 private: |
| 294 ScopedPersistent<v8::Object> m_promise; | 270 ScopedPersistent<v8::Object> m_promise; |
| 295 ScopedPersistent<v8::Function> m_onFulfilled; | 271 ScopedPersistent<v8::Function> m_onFulfilled; |
| 296 ScopedPersistent<v8::Function> m_onRejected; | 272 ScopedPersistent<v8::Function> m_onRejected; |
| 297 ScopedPersistent<v8::Object> m_originatorValueObject; | 273 ScopedPersistent<v8::Object> m_originatorValueObject; |
| 298 RefPtr<ScriptState> m_scriptState; | 274 RefPtr<ScriptState> m_scriptState; |
| 299 }; | 275 }; |
| 300 | 276 |
| 301 void UpdateDerivedTask::performTask(ExecutionContext* context) | 277 void UpdateDerivedTask::performTask(ExecutionContext* context) |
| 302 { | 278 { |
| 303 TaskPerformScopeForInstrumentation performTaskScope(context, this); | |
| 304 | |
| 305 ASSERT(context); | 279 ASSERT(context); |
| 306 if (context->activeDOMObjectsAreStopped()) | 280 if (context->activeDOMObjectsAreStopped()) |
| 307 return; | 281 return; |
| 308 | 282 |
| 309 ScriptState::Scope scope(m_scriptState.get()); | 283 ScriptState::Scope scope(m_scriptState.get()); |
| 310 v8::Isolate* isolate = m_scriptState->isolate(); | 284 v8::Isolate* isolate = m_scriptState->isolate(); |
| 311 v8::Local<v8::Object> originatorValueObject = m_originatorValueObject.newLoc
al(isolate); | 285 v8::Local<v8::Object> originatorValueObject = m_originatorValueObject.newLoc
al(isolate); |
| 312 v8::Local<v8::Value> coercedAlready = V8HiddenValue::getHiddenValue(isolate,
originatorValueObject, V8HiddenValue::thenableHiddenPromise(isolate)); | 286 v8::Local<v8::Value> coercedAlready = V8HiddenValue::getHiddenValue(isolate,
originatorValueObject, V8HiddenValue::thenableHiddenPromise(isolate)); |
| 313 if (!coercedAlready.IsEmpty() && coercedAlready->IsObject()) { | 287 if (!coercedAlready.IsEmpty() && coercedAlready->IsObject()) { |
| 314 ASSERT(V8PromiseCustom::isPromise(coercedAlready.As<v8::Object>(), isola
te)); | 288 ASSERT(V8PromiseCustom::isPromise(coercedAlready.As<v8::Object>(), isola
te)); |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 495 | 469 |
| 496 void PromisePropagator::updateDerivedFromPromise(v8::Handle<v8::Object> derivedP
romise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejecte
d, v8::Handle<v8::Object> promise, v8::Isolate* isolate) | 470 void PromisePropagator::updateDerivedFromPromise(v8::Handle<v8::Object> derivedP
romise, v8::Handle<v8::Function> onFulfilled, v8::Handle<v8::Function> onRejecte
d, v8::Handle<v8::Object> promise, v8::Isolate* isolate) |
| 497 { | 471 { |
| 498 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); | 472 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); |
| 499 V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal); | 473 V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal); |
| 500 if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejecte
d) { | 474 if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejecte
d) { |
| 501 updateDerived(derivedPromise, onFulfilled, onRejected, promise, isolate)
; | 475 updateDerived(derivedPromise, onFulfilled, onRejected, promise, isolate)
; |
| 502 } else { | 476 } else { |
| 503 addToDerived(internal, derivedPromise, onFulfilled, onRejected, isolate)
; | 477 addToDerived(internal, derivedPromise, onFulfilled, onRejected, isolate)
; |
| 504 } | 478 } |
| 505 ExecutionContext* context = currentExecutionContext(isolate); | |
| 506 if (InspectorInstrumentation::isPromiseTrackerEnabled(context)) { | |
| 507 ScriptState* scriptState = ScriptState::current(isolate); | |
| 508 InspectorInstrumentation::didUpdatePromiseParent(context, ScriptObject(s
criptState, derivedPromise), ScriptObject(scriptState, promise)); | |
| 509 } | |
| 510 } | 479 } |
| 511 | 480 |
| 512 } // namespace | 481 } // namespace |
| 513 | 482 |
| 514 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& inf
o) | 483 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& inf
o) |
| 515 { | 484 { |
| 516 v8SetReturnValue(info, v8::Local<v8::Value>()); | 485 v8SetReturnValue(info, v8::Local<v8::Value>()); |
| 517 v8::Isolate* isolate = info.GetIsolate(); | 486 v8::Isolate* isolate = info.GetIsolate(); |
| 518 ExecutionContext* executionContext = callingExecutionContext(isolate); | 487 ExecutionContext* executionContext = callingExecutionContext(isolate); |
| 519 UseCounter::count(executionContext, UseCounter::PromiseConstructor); | 488 UseCounter::count(executionContext, UseCounter::PromiseConstructor); |
| (...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 671 { | 640 { |
| 672 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol
ate); | 641 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol
ate); |
| 673 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); | 642 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); |
| 674 if (internal.IsEmpty()) | 643 if (internal.IsEmpty()) |
| 675 return v8::Local<v8::Object>(); | 644 return v8::Local<v8::Object>(); |
| 676 v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext,
&V8Promise::wrapperTypeInfo, 0, isolate); | 645 v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext,
&V8Promise::wrapperTypeInfo, 0, isolate); |
| 677 | 646 |
| 678 clearDerived(internal, isolate); | 647 clearDerived(internal, isolate); |
| 679 promise->SetInternalField(v8DOMWrapperObjectIndex, internal); | 648 promise->SetInternalField(v8DOMWrapperObjectIndex, internal); |
| 680 | 649 |
| 681 ExecutionContext* context = currentExecutionContext(isolate); | |
| 682 if (InspectorInstrumentation::isPromiseTrackerEnabled(context)) | |
| 683 InspectorInstrumentation::didCreatePromise(context, ScriptObject(ScriptS
tate::current(isolate), promise)); | |
| 684 | |
| 685 setStateForPromise(promise, Pending, v8::Undefined(isolate), isolate); | 650 setStateForPromise(promise, Pending, v8::Undefined(isolate), isolate); |
| 686 return promise; | 651 return promise; |
| 687 } | 652 } |
| 688 | 653 |
| 689 v8::Local<v8::Object> V8PromiseCustom::getInternal(v8::Handle<v8::Object> promis
e) | 654 v8::Local<v8::Object> V8PromiseCustom::getInternal(v8::Handle<v8::Object> promis
e) |
| 690 { | 655 { |
| 691 v8::Local<v8::Value> value = promise->GetInternalField(v8DOMWrapperObjectInd
ex); | 656 v8::Local<v8::Value> value = promise->GetInternalField(v8DOMWrapperObjectInd
ex); |
| 692 return value.As<v8::Object>(); | 657 return value.As<v8::Object>(); |
| 693 } | 658 } |
| 694 | 659 |
| (...skipping 158 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 853 | 818 |
| 854 void V8PromiseCustom::callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8:
:Function> handler, v8::Handle<v8::Value> argument, PromiseState originatorState
, v8::Isolate* isolate) | 819 void V8PromiseCustom::callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8:
:Function> handler, v8::Handle<v8::Value> argument, PromiseState originatorState
, v8::Isolate* isolate) |
| 855 { | 820 { |
| 856 ASSERT(originatorState == Fulfilled || originatorState == Rejected); | 821 ASSERT(originatorState == Fulfilled || originatorState == Rejected); |
| 857 ExecutionContext* executionContext = currentExecutionContext(isolate); | 822 ExecutionContext* executionContext = currentExecutionContext(isolate); |
| 858 ASSERT(executionContext && executionContext->isContextThread()); | 823 ASSERT(executionContext && executionContext->isContextThread()); |
| 859 executionContext->postTask(adoptPtr(new CallHandlerTask(promise, handler, ar
gument, originatorState, isolate, executionContext))); | 824 executionContext->postTask(adoptPtr(new CallHandlerTask(promise, handler, ar
gument, originatorState, isolate, executionContext))); |
| 860 } | 825 } |
| 861 | 826 |
| 862 } // namespace WebCore | 827 } // namespace WebCore |
| OLD | NEW |