Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(86)

Side by Side Diff: Source/bindings/v8/custom/V8PromiseCustom.cpp

Issue 177773002: Support Promises instrumentation on backend. (Closed) Base URL: https://chromium.googlesource.com/chromium/blink.git@master
Patch Set: V8PromiseCustom::setState -> (anonymous namespace)::setStateForPromise + REBASE Created 6 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « Source/bindings/v8/custom/V8PromiseCustom.h ('k') | Source/core/core.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 27 matching lines...) Expand all
38 #include "bindings/v8/ScriptState.h" 38 #include "bindings/v8/ScriptState.h"
39 #include "bindings/v8/V8Binding.h" 39 #include "bindings/v8/V8Binding.h"
40 #include "bindings/v8/V8HiddenValue.h" 40 #include "bindings/v8/V8HiddenValue.h"
41 #include "bindings/v8/V8PerIsolateData.h" 41 #include "bindings/v8/V8PerIsolateData.h"
42 #include "bindings/v8/V8ScriptRunner.h" 42 #include "bindings/v8/V8ScriptRunner.h"
43 #include "bindings/v8/WrapperTypeInfo.h" 43 #include "bindings/v8/WrapperTypeInfo.h"
44 #include "core/dom/Document.h" 44 #include "core/dom/Document.h"
45 #include "core/dom/ExecutionContextTask.h" 45 #include "core/dom/ExecutionContextTask.h"
46 #include "core/frame/DOMWindow.h" 46 #include "core/frame/DOMWindow.h"
47 #include "core/frame/UseCounter.h" 47 #include "core/frame/UseCounter.h"
48 #include "core/inspector/InspectorInstrumentation.h" 48 #include "core/inspector/InspectorPromiseInstrumentation.h"
49 #include "core/workers/WorkerGlobalScope.h" 49 #include "core/workers/WorkerGlobalScope.h"
50 #include "platform/Task.h" 50 #include "platform/Task.h"
51 #include "wtf/Deque.h" 51 #include "wtf/Deque.h"
52 #include "wtf/Functional.h" 52 #include "wtf/Functional.h"
53 #include "wtf/Noncopyable.h" 53 #include "wtf/Noncopyable.h"
54 #include "wtf/PassOwnPtr.h" 54 #include "wtf/PassOwnPtr.h"
55 #include <v8.h> 55 #include <v8.h>
56 56
57 #define V8TRYCATCH_VOID_EMPTY(type, var, value) \ 57 #define V8TRYCATCH_VOID_EMPTY(type, var, value) \
58 type var; \ 58 type var; \
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
193 } 193 }
194 194
195 ASSERT(!derivedPromise.IsEmpty()); 195 ASSERT(!derivedPromise.IsEmpty());
196 derivedPromises->Set(derivedPromises->Length(), derivedPromise); 196 derivedPromises->Set(derivedPromises->Length(), derivedPromise);
197 197
198 // Since they are treated as a tuple, 198 // Since they are treated as a tuple,
199 // we need to guaranteed that the length of these arrays are same. 199 // we need to guaranteed that the length of these arrays are same.
200 ASSERT(fulfillCallbacks->Length() == rejectCallbacks->Length() && rejectCall backs->Length() == derivedPromises->Length()); 200 ASSERT(fulfillCallbacks->Length() == rejectCallbacks->Length() && rejectCall backs->Length() == derivedPromises->Length());
201 } 201 }
202 202
203 // Set a |promise|'s state and result that correspond to the state.
204 // |promise| must be a Promise instance.
205 void setStateForPromise(v8::Handle<v8::Object> promise, V8PromiseCustom::Promise State state, v8::Handle<v8::Value> value, v8::Isolate* isolate)
206 {
207 ASSERT(!value.IsEmpty());
208 ASSERT(state == V8PromiseCustom::Pending || state == V8PromiseCustom::Fulfil led || state == V8PromiseCustom::Rejected || state == V8PromiseCustom::Following );
209 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
210 internal->SetInternalField(V8PromiseCustom::InternalStateIndex, v8::Integer: :New(isolate, state));
211 internal->SetInternalField(V8PromiseCustom::InternalResultIndex, value);
212 ExecutionContext* context = currentExecutionContext(isolate);
213 if (InspectorInstrumentation::isPromiseTrackerEnabled(context))
214 InspectorInstrumentation::didUpdatePromiseState(context, ScriptObject(Sc riptState::forContext(isolate->GetCurrentContext()), promise), state, ScriptValu e(value, isolate));
215 }
216
203 class TaskPerformScopeForInstrumentation { 217 class TaskPerformScopeForInstrumentation {
204 public: 218 public:
205 TaskPerformScopeForInstrumentation(ExecutionContext* context, ExecutionConte xtTask* task) 219 TaskPerformScopeForInstrumentation(ExecutionContext* context, ExecutionConte xtTask* task)
206 : m_cookie(InspectorInstrumentation::willPerformPromiseTask(context, tas k)) 220 : m_cookie(InspectorInstrumentation::willPerformPromiseTask(context, tas k))
207 { 221 {
208 } 222 }
209 223
210 ~TaskPerformScopeForInstrumentation() 224 ~TaskPerformScopeForInstrumentation()
211 { 225 {
212 InspectorInstrumentation::didPerformPromiseTask(m_cookie); 226 InspectorInstrumentation::didPerformPromiseTask(m_cookie);
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 { 407 {
394 while (!m_derivedStack.isEmpty()) { 408 while (!m_derivedStack.isEmpty()) {
395 v8::HandleScope handleScope(isolate); 409 v8::HandleScope handleScope(isolate);
396 OwnPtr<Derived> derived = m_derivedStack.takeLast(); 410 OwnPtr<Derived> derived = m_derivedStack.takeLast();
397 updateDerived(derived->promise(isolate), derived->onFulfilled(isolate), derived->onRejected(isolate), derived->originator(isolate), isolate); 411 updateDerived(derived->promise(isolate), derived->onFulfilled(isolate), derived->onRejected(isolate), derived->originator(isolate), isolate);
398 } 412 }
399 } 413 }
400 414
401 void PromisePropagator::setValue(v8::Handle<v8::Object> promise, v8::Handle<v8:: Value> value, v8::Isolate* isolate) 415 void PromisePropagator::setValue(v8::Handle<v8::Object> promise, v8::Handle<v8:: Value> value, v8::Isolate* isolate)
402 { 416 {
403 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); 417 ASSERT(V8PromiseCustom::getState(V8PromiseCustom::getInternal(promise)) != V 8PromiseCustom::Fulfilled && V8PromiseCustom::getState(V8PromiseCustom::getInter nal(promise)) != V8PromiseCustom::Rejected);
404 ASSERT(V8PromiseCustom::getState(internal) != V8PromiseCustom::Fulfilled && V8PromiseCustom::getState(internal) != V8PromiseCustom::Rejected); 418 setStateForPromise(promise, V8PromiseCustom::Fulfilled, value, isolate);
405 V8PromiseCustom::setState(internal, V8PromiseCustom::Fulfilled, value, isola te);
406 propagateToDerived(promise, isolate); 419 propagateToDerived(promise, isolate);
407 } 420 }
408 421
409 void PromisePropagator::setReason(v8::Handle<v8::Object> promise, v8::Handle<v8: :Value> reason, v8::Isolate* isolate) 422 void PromisePropagator::setReason(v8::Handle<v8::Object> promise, v8::Handle<v8: :Value> reason, v8::Isolate* isolate)
410 { 423 {
411 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); 424 ASSERT(V8PromiseCustom::getState(V8PromiseCustom::getInternal(promise)) != V 8PromiseCustom::Fulfilled && V8PromiseCustom::getState(V8PromiseCustom::getInter nal(promise)) != V8PromiseCustom::Rejected);
412 ASSERT(V8PromiseCustom::getState(internal) != V8PromiseCustom::Fulfilled && V8PromiseCustom::getState(internal) != V8PromiseCustom::Rejected); 425 setStateForPromise(promise, V8PromiseCustom::Rejected, reason, isolate);
413 V8PromiseCustom::setState(internal, V8PromiseCustom::Rejected, reason, isola te);
414 propagateToDerived(promise, isolate); 426 propagateToDerived(promise, isolate);
415 } 427 }
416 428
417 void PromisePropagator::propagateToDerived(v8::Handle<v8::Object> promise, v8::I solate* isolate) 429 void PromisePropagator::propagateToDerived(v8::Handle<v8::Object> promise, v8::I solate* isolate)
418 { 430 {
419 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); 431 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
420 ASSERT(V8PromiseCustom::getState(internal) == V8PromiseCustom::Fulfilled || V8PromiseCustom::getState(internal) == V8PromiseCustom::Rejected); 432 ASSERT(V8PromiseCustom::getState(internal) == V8PromiseCustom::Fulfilled || V8PromiseCustom::getState(internal) == V8PromiseCustom::Rejected);
421 v8::Local<v8::Array> fulfillCallbacks = internal->GetInternalField(V8Promise Custom::InternalFulfillCallbackIndex).As<v8::Array>(); 433 v8::Local<v8::Array> fulfillCallbacks = internal->GetInternalField(V8Promise Custom::InternalFulfillCallbackIndex).As<v8::Array>();
422 v8::Local<v8::Array> rejectCallbacks = internal->GetInternalField(V8PromiseC ustom::InternalRejectCallbackIndex).As<v8::Array>(); 434 v8::Local<v8::Array> rejectCallbacks = internal->GetInternalField(V8PromiseC ustom::InternalRejectCallbackIndex).As<v8::Array>();
423 v8::Local<v8::Array> derivedPromises = internal->GetInternalField(V8PromiseC ustom::InternalDerivedPromiseIndex).As<v8::Array>(); 435 v8::Local<v8::Array> derivedPromises = internal->GetInternalField(V8PromiseC ustom::InternalDerivedPromiseIndex).As<v8::Array>();
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
484 496
485 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 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)
486 { 498 {
487 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); 499 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise);
488 V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal); 500 V8PromiseCustom::PromiseState state = V8PromiseCustom::getState(internal);
489 if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejecte d) { 501 if (state == V8PromiseCustom::Fulfilled || state == V8PromiseCustom::Rejecte d) {
490 updateDerived(derivedPromise, onFulfilled, onRejected, promise, isolate) ; 502 updateDerived(derivedPromise, onFulfilled, onRejected, promise, isolate) ;
491 } else { 503 } else {
492 addToDerived(internal, derivedPromise, onFulfilled, onRejected, isolate) ; 504 addToDerived(internal, derivedPromise, onFulfilled, onRejected, isolate) ;
493 } 505 }
506 ExecutionContext* context = currentExecutionContext(isolate);
507 if (InspectorInstrumentation::isPromiseTrackerEnabled(context)) {
508 ScriptState* scriptState = ScriptState::forContext(isolate->GetCurrentCo ntext());
509 InspectorInstrumentation::didUpdatePromiseParent(context, ScriptObject(s criptState, derivedPromise), ScriptObject(scriptState, promise));
510 }
494 } 511 }
495 512
496 } // namespace 513 } // namespace
497 514
498 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& inf o) 515 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& inf o)
499 { 516 {
500 v8SetReturnValue(info, v8::Local<v8::Value>()); 517 v8SetReturnValue(info, v8::Local<v8::Value>());
501 v8::Isolate* isolate = info.GetIsolate(); 518 v8::Isolate* isolate = info.GetIsolate();
502 ExecutionContext* executionContext = callingExecutionContext(isolate); 519 ExecutionContext* executionContext = callingExecutionContext(isolate);
503 UseCounter::count(executionContext, UseCounter::PromiseConstructor); 520 UseCounter::count(executionContext, UseCounter::PromiseConstructor);
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after
653 // -- V8PromiseCustom -- 670 // -- V8PromiseCustom --
654 v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> crea tionContext, v8::Isolate* isolate) 671 v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> crea tionContext, v8::Isolate* isolate)
655 { 672 {
656 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol ate); 673 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol ate);
657 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); 674 v8::Local<v8::Object> internal = internalTemplate->NewInstance();
658 if (internal.IsEmpty()) 675 if (internal.IsEmpty())
659 return v8::Local<v8::Object>(); 676 return v8::Local<v8::Object>();
660 v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::wrapperTypeInfo, 0, isolate); 677 v8::Local<v8::Object> promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::wrapperTypeInfo, 0, isolate);
661 678
662 clearDerived(internal, isolate); 679 clearDerived(internal, isolate);
663 setState(internal, Pending, v8::Undefined(isolate), isolate); 680 promise->SetInternalField(v8DOMWrapperObjectIndex, internal);
664 681
665 promise->SetInternalField(v8DOMWrapperObjectIndex, internal); 682 ExecutionContext* context = currentExecutionContext(isolate);
683 if (InspectorInstrumentation::isPromiseTrackerEnabled(context))
684 InspectorInstrumentation::didCreatePromise(context, ScriptObject(ScriptS tate::forContext(isolate->GetCurrentContext()), promise));
685
686 setStateForPromise(promise, Pending, v8::Undefined(isolate), isolate);
666 return promise; 687 return promise;
667 } 688 }
668 689
669 v8::Local<v8::Object> V8PromiseCustom::getInternal(v8::Handle<v8::Object> promis e) 690 v8::Local<v8::Object> V8PromiseCustom::getInternal(v8::Handle<v8::Object> promis e)
670 { 691 {
671 v8::Local<v8::Value> value = promise->GetInternalField(v8DOMWrapperObjectInd ex); 692 v8::Local<v8::Value> value = promise->GetInternalField(v8DOMWrapperObjectInd ex);
672 return value.As<v8::Object>(); 693 return value.As<v8::Object>();
673 } 694 }
674 695
675 V8PromiseCustom::PromiseState V8PromiseCustom::getState(v8::Handle<v8::Object> i nternal) 696 V8PromiseCustom::PromiseState V8PromiseCustom::getState(v8::Handle<v8::Object> i nternal)
676 { 697 {
677 v8::Handle<v8::Value> value = internal->GetInternalField(V8PromiseCustom::In ternalStateIndex); 698 v8::Handle<v8::Value> value = internal->GetInternalField(V8PromiseCustom::In ternalStateIndex);
678 uint32_t number = toInt32(value); 699 uint32_t number = toInt32(value);
679 ASSERT(number == Pending || number == Fulfilled || number == Rejected || num ber == Following); 700 ASSERT(number == Pending || number == Fulfilled || number == Rejected || num ber == Following);
680 return static_cast<PromiseState>(number); 701 return static_cast<PromiseState>(number);
681 } 702 }
682 703
683 void V8PromiseCustom::setState(v8::Handle<v8::Object> internal, PromiseState sta te, v8::Handle<v8::Value> value, v8::Isolate* isolate)
684 {
685 ASSERT(!value.IsEmpty());
686 ASSERT(state == Pending || state == Fulfilled || state == Rejected || state == Following);
687 internal->SetInternalField(InternalStateIndex, v8::Integer::New(isolate, sta te));
688 internal->SetInternalField(InternalResultIndex, value);
689 }
690
691 bool V8PromiseCustom::isPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate* isolate) 704 bool V8PromiseCustom::isPromise(v8::Handle<v8::Value> maybePromise, v8::Isolate* isolate)
692 { 705 {
693 return V8Promise::domTemplate(isolate)->HasInstance(maybePromise); 706 return V8Promise::domTemplate(isolate)->HasInstance(maybePromise);
694 } 707 }
695 708
696 v8::Local<v8::Object> V8PromiseCustom::toPromise(v8::Handle<v8::Value> maybeProm ise, v8::Isolate* isolate) 709 v8::Local<v8::Object> V8PromiseCustom::toPromise(v8::Handle<v8::Value> maybeProm ise, v8::Isolate* isolate)
697 { 710 {
698 // FIXME: Currently we don't check [[PromiseConstructor]] since we limit 711 // FIXME: Currently we don't check [[PromiseConstructor]] since we limit
699 // the creation of the promise objects only from the Blink Promise 712 // the creation of the promise objects only from the Blink Promise
700 // constructor. 713 // constructor.
(...skipping 17 matching lines...) Expand all
718 731
719 if (isPromise(result, isolate)) { 732 if (isPromise(result, isolate)) {
720 v8::Local<v8::Object> valuePromise = result.As<v8::Object>(); 733 v8::Local<v8::Object> valuePromise = result.As<v8::Object>();
721 v8::Local<v8::Object> valueInternal = getInternal(valuePromise); 734 v8::Local<v8::Object> valueInternal = getInternal(valuePromise);
722 PromiseState valueState = getState(valueInternal); 735 PromiseState valueState = getState(valueInternal);
723 if (promise->SameValue(valuePromise)) { 736 if (promise->SameValue(valuePromise)) {
724 v8::Local<v8::Value> reason = V8ThrowException::createTypeError("Res olve a promise with itself", isolate); 737 v8::Local<v8::Value> reason = V8ThrowException::createTypeError("Res olve a promise with itself", isolate);
725 setReason(promise, reason, isolate); 738 setReason(promise, reason, isolate);
726 } else if (valueState == Following) { 739 } else if (valueState == Following) {
727 v8::Local<v8::Object> valuePromiseFollowing = valueInternal->GetInte rnalField(InternalResultIndex).As<v8::Object>(); 740 v8::Local<v8::Object> valuePromiseFollowing = valueInternal->GetInte rnalField(InternalResultIndex).As<v8::Object>();
728 setState(internal, Following, valuePromiseFollowing, isolate); 741 setStateForPromise(promise, Following, valuePromiseFollowing, isolat e);
729 addToDerived(getInternal(valuePromiseFollowing), promise, v8::Handle <v8::Function>(), v8::Handle<v8::Function>(), isolate); 742 addToDerived(getInternal(valuePromiseFollowing), promise, v8::Handle <v8::Function>(), v8::Handle<v8::Function>(), isolate);
730 } else if (valueState == Fulfilled) { 743 } else if (valueState == Fulfilled) {
731 setValue(promise, valueInternal->GetInternalField(InternalResultInde x), isolate); 744 setValue(promise, valueInternal->GetInternalField(InternalResultInde x), isolate);
732 } else if (valueState == Rejected) { 745 } else if (valueState == Rejected) {
733 setReason(promise, valueInternal->GetInternalField(InternalResultInd ex), isolate); 746 setReason(promise, valueInternal->GetInternalField(InternalResultInd ex), isolate);
734 } else { 747 } else {
735 ASSERT(valueState == Pending); 748 ASSERT(valueState == Pending);
736 setState(internal, Following, valuePromise, isolate); 749 setStateForPromise(promise, Following, valuePromise, isolate);
737 addToDerived(valueInternal, promise, v8::Handle<v8::Function>(), v8: :Handle<v8::Function>(), isolate); 750 addToDerived(valueInternal, promise, v8::Handle<v8::Function>(), v8: :Handle<v8::Function>(), isolate);
738 } 751 }
739 } else { 752 } else {
740 setValue(promise, result, isolate); 753 setValue(promise, result, isolate);
741 } 754 }
742 } 755 }
743 756
744 void V8PromiseCustom::reject(v8::Handle<v8::Object> promise, v8::Handle<v8::Valu e> reason, v8::Isolate* isolate) 757 void V8PromiseCustom::reject(v8::Handle<v8::Object> promise, v8::Handle<v8::Valu e> reason, v8::Isolate* isolate)
745 { 758 {
746 v8::Local<v8::Object> internal = getInternal(promise); 759 v8::Local<v8::Object> internal = getInternal(promise);
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
841 854
842 void V8PromiseCustom::callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8: :Function> handler, v8::Handle<v8::Value> argument, PromiseState originatorState , v8::Isolate* isolate) 855 void V8PromiseCustom::callHandler(v8::Handle<v8::Object> promise, v8::Handle<v8: :Function> handler, v8::Handle<v8::Value> argument, PromiseState originatorState , v8::Isolate* isolate)
843 { 856 {
844 ASSERT(originatorState == Fulfilled || originatorState == Rejected); 857 ASSERT(originatorState == Fulfilled || originatorState == Rejected);
845 ExecutionContext* executionContext = currentExecutionContext(isolate); 858 ExecutionContext* executionContext = currentExecutionContext(isolate);
846 ASSERT(executionContext && executionContext->isContextThread()); 859 ASSERT(executionContext && executionContext->isContextThread());
847 executionContext->postTask(adoptPtr(new CallHandlerTask(promise, handler, ar gument, originatorState, isolate, executionContext))); 860 executionContext->postTask(adoptPtr(new CallHandlerTask(promise, handler, ar gument, originatorState, isolate, executionContext)));
848 } 861 }
849 862
850 } // namespace WebCore 863 } // namespace WebCore
OLDNEW
« no previous file with comments | « Source/bindings/v8/custom/V8PromiseCustom.h ('k') | Source/core/core.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698