File: ScriptPromiseProperty.h

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (159 lines) | stat: -rw-r--r-- 6,241 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef ScriptPromiseProperty_h
#define ScriptPromiseProperty_h

#include "bindings/core/v8/ScriptPromise.h"
#include "bindings/core/v8/ScriptPromisePropertyBase.h"
#include "bindings/core/v8/ToV8.h"
#include "wtf/Noncopyable.h"
#include "wtf/PassRefPtr.h"

namespace blink {

class ExecutionContext;

// ScriptPromiseProperty is a helper for implementing a DOM method or
// attribute whose value is a Promise, and the same Promise must be
// returned each time.
//
// ScriptPromiseProperty does not keep Promises or worlds alive to
// deliver Promise resolution/rejection to them; the Promise
// resolution/rejections are delivered if the holder's wrapper is
// alive. This is achieved by keeping a weak reference from
// ScriptPromiseProperty to the holder's wrapper, and references in
// hidden values from the wrapper to the promise and resolver
// (coincidentally the Resolver and Promise may be the same object,
// but that is an implementation detail of v8.)
//
//                                             ----> Resolver
//                                            /
// ScriptPromiseProperty - - -> Holder Wrapper ----> Promise
//
// To avoid exposing the action of the garbage collector to script,
// you should keep the wrapper alive as long as a promise may be
// settled.
//
// To avoid clobbering hidden values, a holder should only have one
// ScriptPromiseProperty object for a given name at a time. See reset.
template<typename HolderType, typename ResolvedType, typename RejectedType>
class ScriptPromiseProperty : public ScriptPromisePropertyBase {
    WTF_MAKE_NONCOPYABLE(ScriptPromiseProperty);
public:
    // Creates a ScriptPromiseProperty that will create Promises in
    // the specified ExecutionContext for a property of 'holder'
    // (typically ScriptPromiseProperty should be a member of the
    // property holder).
    //
    // When implementing a ScriptPromiseProperty add the property name
    // to ScriptPromiseProperties.h and pass
    // ScriptPromiseProperty::Foo to create. The name must be unique
    // per kind of holder.
    template<typename PassHolderType>
    ScriptPromiseProperty(ExecutionContext*, PassHolderType, Name);

    virtual ~ScriptPromiseProperty() { }

    template<typename PassResolvedType>
    void resolve(PassResolvedType);

    template<typename PassRejectedType>
    void reject(PassRejectedType);

    // Resets this property by unregistering the Promise property from the
    // holder wrapper. Resets the internal state to Pending and clears the
    // resolved and the rejected values.
    // This method keeps the holder object and the property name.
    void reset();

    virtual void trace(Visitor*) override;

private:
    virtual v8::Handle<v8::Object> holder(v8::Handle<v8::Object> creationContext, v8::Isolate*) override;
    virtual v8::Handle<v8::Value> resolvedValue(v8::Isolate*, v8::Handle<v8::Object> creationContext) override;
    virtual v8::Handle<v8::Value> rejectedValue(v8::Isolate*, v8::Handle<v8::Object> creationContext) override;

    HolderType m_holder;
    ResolvedType m_resolved;
    RejectedType m_rejected;
};

template<typename HolderType, typename ResolvedType, typename RejectedType>
template<typename PassHolderType>
ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::ScriptPromiseProperty(ExecutionContext* executionContext, PassHolderType holder, Name name)
    : ScriptPromisePropertyBase(executionContext, name)
    , m_holder(holder)
{
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
template<typename PassResolvedType>
void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolve(PassResolvedType value)
{
    if (state() != Pending) {
        ASSERT_NOT_REACHED();
        return;
    }
    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
        return;
    m_resolved = value;
    resolveOrReject(Resolved);
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
template<typename PassRejectedType>
void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reject(PassRejectedType value)
{
    if (state() != Pending) {
        ASSERT_NOT_REACHED();
        return;
    }
    if (!executionContext() || executionContext()->activeDOMObjectsAreStopped())
        return;
    m_rejected = value;
    resolveOrReject(Rejected);
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
v8::Handle<v8::Object> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::holder(v8::Handle<v8::Object> creationContext, v8::Isolate* isolate)
{
    v8::Handle<v8::Value> value = toV8(m_holder, creationContext, isolate);
    return value.As<v8::Object>();
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::resolvedValue(v8::Isolate* isolate, v8::Handle<v8::Object> creationContext)
{
    ASSERT(state() == Resolved);
    return toV8(m_resolved, creationContext, isolate);
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
v8::Handle<v8::Value> ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::rejectedValue(v8::Isolate* isolate, v8::Handle<v8::Object> creationContext)
{
    ASSERT(state() == Rejected);
    return toV8(m_rejected, creationContext, isolate);
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::reset()
{
    resetBase();
    m_resolved = ResolvedType();
    m_rejected = RejectedType();
}

template<typename HolderType, typename ResolvedType, typename RejectedType>
void ScriptPromiseProperty<HolderType, ResolvedType, RejectedType>::trace(Visitor* visitor)
{
    TraceIfNeeded<HolderType>::trace(visitor, &m_holder);
    TraceIfNeeded<ResolvedType>::trace(visitor, &m_resolved);
    TraceIfNeeded<RejectedType>::trace(visitor, &m_rejected);
    ScriptPromisePropertyBase::trace(visitor);
}

} // namespace blink

#endif // ScriptPromiseProperty_h