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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 #include "core/page/DOMWindow.h" | 44 #include "core/page/DOMWindow.h" |
45 #include "core/platform/Task.h" | 45 #include "core/platform/Task.h" |
46 #include "wtf/Functional.h" | 46 #include "wtf/Functional.h" |
47 #include "wtf/PassOwnPtr.h" | 47 #include "wtf/PassOwnPtr.h" |
48 #include <v8.h> | 48 #include <v8.h> |
49 | 49 |
50 namespace WebCore { | 50 namespace WebCore { |
51 | 51 |
52 namespace { | 52 namespace { |
53 | 53 |
| 54 int promiseFulfillCallbackTag = 0; |
| 55 int promiseResolveCallbackTag = 0; |
| 56 int promiseRejectCallbackTag = 0; |
| 57 |
| 58 v8::Local<v8::Function> getFunction(v8::FunctionCallback callback, int* tag, v8:
:Isolate* isolate) |
| 59 { |
| 60 // tag must be a pointer of one of the above tags. |
| 61 ASSERT(tag == &promiseFulfillCallbackTag |
| 62 || tag == &promiseResolveCallbackTag |
| 63 || tag == &promiseRejectCallbackTag); |
| 64 WrapperWorldType worldType = WebCore::worldType(isolate); |
| 65 V8PerIsolateData* data = V8PerIsolateData::from(isolate); |
| 66 ASSERT(data); |
| 67 V8PerIsolateData::TemplateMap::iterator result = data->templateMap(worldType
).find(tag); |
| 68 if (result != data->templateMap(worldType).end()) |
| 69 return result->value.newLocal(isolate)->GetFunction(); |
| 70 |
| 71 v8::Handle<v8::FunctionTemplate> functionTemplate = v8::FunctionTemplate::Ne
w(callback); |
| 72 data->templateMap(worldType).add(tag, UnsafePersistent<v8::FunctionTemplate>
(isolate, functionTemplate)); |
| 73 return functionTemplate->GetFunction(); |
| 74 } |
| 75 |
54 class PromiseTask : public ScriptExecutionContext::Task { | 76 class PromiseTask : public ScriptExecutionContext::Task { |
55 public: | 77 public: |
56 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv
er, v8::Handle<v8::Value> result) | 78 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv
er, v8::Handle<v8::Value> result) |
57 : m_callback(callback) | 79 : m_callback(callback) |
58 , m_receiver(receiver) | 80 , m_receiver(receiver) |
59 , m_result(result) | 81 , m_result(result) |
60 { | 82 { |
61 ASSERT(!m_callback.isEmpty()); | 83 ASSERT(!m_callback.isEmpty()); |
62 ASSERT(!m_receiver.isEmpty()); | 84 ASSERT(!m_receiver.isEmpty()); |
63 ASSERT(!m_result.isEmpty()); | 85 ASSERT(!m_result.isEmpty()); |
(...skipping 26 matching lines...) Expand all Loading... |
90 v8::Handle<v8::Value> postTask(v8::Handle<v8::Function> callback, v8::Handle<v8:
:Object> receiver, v8::Handle<v8::Value> value, v8::Isolate* isolate) | 112 v8::Handle<v8::Value> postTask(v8::Handle<v8::Function> callback, v8::Handle<v8:
:Object> receiver, v8::Handle<v8::Value> value, v8::Isolate* isolate) |
91 { | 113 { |
92 DOMWindow* window = activeDOMWindow(); | 114 DOMWindow* window = activeDOMWindow(); |
93 ASSERT(window); | 115 ASSERT(window); |
94 Document* document = window->document(); | 116 Document* document = window->document(); |
95 ASSERT(document); | 117 ASSERT(document); |
96 document->postTask(adoptPtr(new PromiseTask(callback, receiver, value))); | 118 document->postTask(adoptPtr(new PromiseTask(callback, receiver, value))); |
97 return v8::Undefined(isolate); | 119 return v8::Undefined(isolate); |
98 } | 120 } |
99 | 121 |
| 122 // This function must have the resolver as the first argument when called |
| 123 // See promiseCallback. |
| 124 void promiseFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
| 125 { |
| 126 v8::Local<v8::Object> resolver; |
| 127 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
| 128 ASSERT(args.Length() > 0); |
| 129 resolver = args[0].As<v8::Object>(); |
| 130 if (args.Length() > 1) |
| 131 result = args[1]; |
| 132 |
| 133 V8PromiseCustom::fulfillResolver(resolver, result, V8PromiseCustom::Synchron
ous, args.GetIsolate()); |
| 134 } |
| 135 |
| 136 // This function must be bound with the resolver as the first argument. |
| 137 // See promiseCallback. |
| 138 void promiseResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
| 139 { |
| 140 v8::Local<v8::Object> resolver; |
| 141 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
| 142 ASSERT(args.Length() > 0); |
| 143 resolver = args[0].As<v8::Object>(); |
| 144 if (args.Length() > 1) |
| 145 result = args[1]; |
| 146 |
| 147 V8PromiseCustom::resolveResolver(resolver, result, V8PromiseCustom::Synchron
ous, args.GetIsolate()); |
| 148 } |
| 149 |
| 150 // This function must be bound with the resolver as the first argument. |
| 151 // See promiseCallback. |
| 152 void promiseRejectCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
| 153 { |
| 154 v8::Local<v8::Object> resolver; |
| 155 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
| 156 ASSERT(args.Length() > 0); |
| 157 resolver = args[0].As<v8::Object>(); |
| 158 if (args.Length() > 1) |
| 159 result = args[1]; |
| 160 |
| 161 V8PromiseCustom::rejectResolver(resolver, result, V8PromiseCustom::Synchrono
us, args.GetIsolate()); |
| 162 } |
| 163 |
| 164 v8::Local<v8::Function> promiseCallback(v8::Handle<v8::Object> resolver, V8Promi
seCustom::PromiseAlgorithm algorithm, v8::Isolate* isolate) |
| 165 { |
| 166 v8::Local<v8::Function> callback; |
| 167 switch (algorithm) { |
| 168 case V8PromiseCustom::FulfillAlgorithm: |
| 169 callback = getFunction(promiseFulfillCallback, &promiseFulfillCallbackTa
g, isolate); |
| 170 break; |
| 171 case V8PromiseCustom::ResolveAlgorithm: |
| 172 callback = getFunction(promiseResolveCallback, &promiseResolveCallbackTa
g, isolate); |
| 173 break; |
| 174 case V8PromiseCustom::RejectAlgorithm: |
| 175 callback = getFunction(promiseRejectCallback, &promiseRejectCallbackTag,
isolate); |
| 176 break; |
| 177 default: |
| 178 ASSERT(0); |
| 179 } |
| 180 // We bind |resolver| to promise{Fulfill, Resolve, Reject}Callback. |
| 181 // |
| 182 // promiseCallback(result) will be evaluated as |
| 183 // promiseFulfillCallback(resolver, result), |
| 184 // if algorithm is FulfillAlgorithm. |
| 185 |
| 186 // FIXME: If there is a way to bind an object to a function other than evalu
ate a JavaScript, it will be preferable. |
| 187 // We should not depend on the global context that user can change, such as
accessing a property, calling a method or so. |
| 188 v8::Local<v8::String> script = v8String("(function(f, v1) { return function(
v2) { return f(v1, v2); }; })", isolate); |
| 189 v8::Local<v8::Value> value = V8ScriptRunner::compileAndRunInternalScript(scr
ipt, isolate); |
| 190 |
| 191 v8::Local<v8::Value> argv[] = { |
| 192 callback, |
| 193 resolver, |
| 194 }; |
| 195 v8::Local<v8::Object> receiver = isolate->GetCurrentContext()->Global(); |
| 196 |
| 197 value = V8ScriptRunner::callFunction(value.As<v8::Function>(), getScriptExec
utionContext(), receiver, WTF_ARRAY_LENGTH(argv), argv); |
| 198 ASSERT(!value.IsEmpty()); |
| 199 return value.As<v8::Function>(); |
| 200 } |
| 201 |
100 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result
, V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) | 202 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result
, V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) |
101 { | 203 { |
102 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); | 204 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); |
103 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { | 205 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { |
104 v8::Local<v8::Value> value = callbacks->Get(i); | 206 v8::Local<v8::Value> value = callbacks->Get(i); |
105 v8::Local<v8::Function> callback = value.As<v8::Function>(); | 207 v8::Local<v8::Function> callback = value.As<v8::Function>(); |
106 V8PromiseCustom::call(callback, global, result, mode, isolate); | 208 V8PromiseCustom::call(callback, global, result, mode, isolate); |
107 } | 209 } |
108 } | 210 } |
109 | 211 |
110 } // namespace | 212 } // namespace |
111 | 213 |
112 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& arg
s) | 214 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& arg
s) |
113 { | 215 { |
114 v8SetReturnValue(args, v8::Local<v8::Value>()); | 216 v8SetReturnValue(args, v8::Local<v8::Value>()); |
115 v8::Isolate* isolate = args.GetIsolate(); | 217 v8::Isolate* isolate = args.GetIsolate(); |
116 if (!args.Length() || !args[0]->IsFunction()) { | 218 if (!args.Length() || !args[0]->IsFunction()) { |
117 throwTypeError("Promise constructor takes a function argument", isolate)
; | 219 throwTypeError("Promise constructor takes a function argument", isolate)
; |
118 return; | 220 return; |
119 } | 221 } |
120 v8::Local<v8::Function> init = args[0].As<v8::Function>(); | 222 v8::Local<v8::Function> init = args[0].As<v8::Function>(); |
121 v8::Local<v8::Object> promise, resolver; | 223 v8::Local<v8::Object> promise, resolver; |
122 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 224 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
123 v8::Handle<v8::Value> argv[] = { | 225 v8::Handle<v8::Value> argv[] = { |
124 resolver, | 226 resolver, |
125 }; | 227 }; |
126 v8::TryCatch trycatch; | 228 v8::TryCatch trycatch; |
127 if (V8ScriptRunner::callFunction(init, getScriptExecutionContext(), promise,
WTF_ARRAY_LENGTH(argv), argv).IsEmpty()) { | 229 if (V8ScriptRunner::callFunction(init, getScriptExecutionContext(), promise,
WTF_ARRAY_LENGTH(argv), argv).IsEmpty()) { |
128 // An exception is thrown. Reject the promise. | 230 // An exception is thrown. Reject the promise if its resolved flag is un
set. |
129 V8PromiseCustom::rejectResolver(resolver, trycatch.Exception(), V8Promis
eCustom::Asynchronous, isolate); | 231 if (!V8PromiseCustom::isInternalDetached(resolver) && V8PromiseCustom::g
etState(V8PromiseCustom::getInternal(resolver)) == V8PromiseCustom::Pending) |
| 232 V8PromiseCustom::rejectResolver(resolver, trycatch.Exception(), V8Pr
omiseCustom::Asynchronous, isolate); |
130 } | 233 } |
131 v8SetReturnValue(args, promise); | 234 v8SetReturnValue(args, promise); |
132 return; | 235 return; |
133 } | 236 } |
134 | 237 |
135 // | 238 // |
136 // -- V8PromiseCustom -- | 239 // -- V8PromiseCustom -- |
137 void V8PromiseCustom::createPromise(v8::Handle<v8::Object> creationContext, v8::
Local<v8::Object>* promise, v8::Local<v8::Object>* resolver, v8::Isolate* isolat
e) | 240 void V8PromiseCustom::createPromise(v8::Handle<v8::Object> creationContext, v8::
Local<v8::Object>* promise, v8::Local<v8::Object>* resolver, v8::Isolate* isolat
e) |
138 { | 241 { |
139 // FIXME: v8::ObjectTemplate::New should be cached. | 242 // FIXME: v8::ObjectTemplate::New should be cached. |
140 v8::Local<v8::ObjectTemplate> internalTemplate = v8::ObjectTemplate::New(); | 243 v8::Local<v8::ObjectTemplate> internalTemplate = v8::ObjectTemplate::New(); |
141 internalTemplate->SetInternalFieldCount(InternalFieldCount); | 244 internalTemplate->SetInternalFieldCount(InternalFieldCount); |
142 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); | 245 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); |
143 *promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::info, 0,
isolate); | 246 *promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::info, 0,
isolate); |
144 *resolver = V8DOMWrapper::createWrapper(creationContext, &V8PromiseResolver:
:info, 0, isolate); | 247 *resolver = V8DOMWrapper::createWrapper(creationContext, &V8PromiseResolver:
:info, 0, isolate); |
145 | 248 |
146 clearInternal(internal, V8PromiseCustom::Pending, v8::Undefined(isolate)); | 249 clearInternal(internal, V8PromiseCustom::Pending, v8::Undefined(isolate)); |
147 | 250 |
148 (*promise)->SetInternalField(v8DOMWrapperObjectIndex, internal); | 251 (*promise)->SetInternalField(v8DOMWrapperObjectIndex, internal); |
149 (*resolver)->SetInternalField(v8DOMWrapperObjectIndex, internal); | 252 (*resolver)->SetInternalField(v8DOMWrapperObjectIndex, internal); |
150 } | 253 } |
151 | 254 |
152 void V8PromiseCustom::fulfillResolver(v8::Handle<v8::Object> resolver, v8::Handl
e<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) | 255 void V8PromiseCustom::fulfillResolver(v8::Handle<v8::Object> resolver, v8::Handl
e<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) |
153 { | 256 { |
154 if (isInternalDetached(resolver)) | 257 if (isInternalDetached(resolver)) |
155 return; | 258 return; |
156 v8::Local<v8::Object> internal = getInternal(resolver); | 259 v8::Local<v8::Object> internal = getInternal(resolver); |
157 if (getState(internal) != Pending) | 260 ASSERT(getState(internal) == Pending || getState(internal) == PendingWithRes
olvedFlagSet); |
158 return; | |
159 | |
160 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom:
:InternalFulfillCallbackIndex).As<v8::Array>(); | 261 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom:
:InternalFulfillCallbackIndex).As<v8::Array>(); |
161 clearInternal(internal, Fulfilled, result); | 262 clearInternal(internal, Fulfilled, result); |
162 detachInternal(resolver, isolate); | 263 detachInternal(resolver, isolate); |
163 | 264 |
164 callCallbacks(callbacks, result, mode, isolate); | 265 callCallbacks(callbacks, result, mode, isolate); |
165 } | 266 } |
166 | 267 |
| 268 void V8PromiseCustom::resolveResolver(v8::Handle<v8::Object> resolver, v8::Handl
e<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) |
| 269 { |
| 270 ASSERT(!result.IsEmpty()); |
| 271 v8::Local<v8::Value> then; |
| 272 if (result->IsObject()) { |
| 273 v8::TryCatch trycatch; |
| 274 then = result.As<v8::Object>()->Get(v8::String::NewSymbol("then")); |
| 275 if (then.IsEmpty()) { |
| 276 // If calling the [[Get]] internal method threw an exception, catch
it and run reject. |
| 277 rejectResolver(resolver, trycatch.Exception(), mode, isolate); |
| 278 return; |
| 279 } |
| 280 } |
| 281 |
| 282 if (!then.IsEmpty() && then->IsFunction()) { |
| 283 ASSERT(result->IsObject()); |
| 284 v8::TryCatch trycatch; |
| 285 v8::Handle<v8::Value> argv[] = { |
| 286 promiseCallback(resolver, ResolveAlgorithm, isolate), |
| 287 promiseCallback(resolver, RejectAlgorithm, isolate), |
| 288 }; |
| 289 if (V8ScriptRunner::callFunction(then.As<v8::Function>(), getScriptExecu
tionContext(), result.As<v8::Object>(), WTF_ARRAY_LENGTH(argv), argv).IsEmpty()) |
| 290 rejectResolver(resolver, trycatch.Exception(), mode, isolate); |
| 291 return; |
| 292 } |
| 293 |
| 294 fulfillResolver(resolver, result, mode, isolate); |
| 295 } |
| 296 |
167 void V8PromiseCustom::rejectResolver(v8::Handle<v8::Object> resolver, v8::Handle
<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) | 297 void V8PromiseCustom::rejectResolver(v8::Handle<v8::Object> resolver, v8::Handle
<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) |
168 { | 298 { |
169 if (isInternalDetached(resolver)) | 299 if (isInternalDetached(resolver)) |
170 return; | 300 return; |
171 v8::Local<v8::Object> internal = getInternal(resolver); | 301 v8::Local<v8::Object> internal = getInternal(resolver); |
172 if (getState(internal) != Pending) | 302 ASSERT(getState(internal) == Pending || getState(internal) == PendingWithRes
olvedFlagSet); |
173 return; | |
174 | |
175 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom:
:InternalRejectCallbackIndex).As<v8::Array>(); | 303 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom:
:InternalRejectCallbackIndex).As<v8::Array>(); |
176 clearInternal(internal, Rejected, result); | 304 clearInternal(internal, Rejected, result); |
177 detachInternal(resolver, isolate); | 305 detachInternal(resolver, isolate); |
178 | 306 |
179 callCallbacks(callbacks, result, mode, isolate); | 307 callCallbacks(callbacks, result, mode, isolate); |
180 } | 308 } |
181 | 309 |
182 void V8PromiseCustom::append(v8::Handle<v8::Object> promise, v8::Handle<v8::Func
tion> fulfillCallback, v8::Handle<v8::Function> rejectCallback, v8::Isolate* iso
late) | 310 void V8PromiseCustom::append(v8::Handle<v8::Object> promise, v8::Handle<v8::Func
tion> fulfillCallback, v8::Handle<v8::Function> rejectCallback, v8::Isolate* iso
late) |
183 { | 311 { |
184 // fulfillCallback and rejectCallback can be empty. | 312 // fulfillCallback and rejectCallback can be empty. |
185 v8::Local<v8::Object> internal = getInternal(promise).As<v8::Object>(); | 313 v8::Local<v8::Object> internal = getInternal(promise); |
186 | 314 |
187 PromiseState state = getState(internal); | 315 PromiseState state = getState(internal); |
188 if (state == Fulfilled) { | 316 if (state == Fulfilled) { |
189 if (!fulfillCallback.IsEmpty()) { | 317 if (!fulfillCallback.IsEmpty()) { |
190 v8::Local<v8::Value> result = internal->GetInternalField(V8PromiseCu
stom::InternalResultIndex); | 318 v8::Local<v8::Value> result = internal->GetInternalField(V8PromiseCu
stom::InternalResultIndex); |
191 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(
); | 319 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(
); |
192 call(fulfillCallback, global, result, Asynchronous, isolate); | 320 call(fulfillCallback, global, result, Asynchronous, isolate); |
193 } | 321 } |
194 return; | 322 return; |
195 } | 323 } |
196 if (state == Rejected) { | 324 if (state == Rejected) { |
197 if (!rejectCallback.IsEmpty()) { | 325 if (!rejectCallback.IsEmpty()) { |
198 v8::Local<v8::Value> result = internal->GetInternalField(V8PromiseCu
stom::InternalResultIndex); | 326 v8::Local<v8::Value> result = internal->GetInternalField(V8PromiseCu
stom::InternalResultIndex); |
199 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(
); | 327 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(
); |
200 call(rejectCallback, global, result, Asynchronous, isolate); | 328 call(rejectCallback, global, result, Asynchronous, isolate); |
201 } | 329 } |
202 return; | 330 return; |
203 } | 331 } |
204 | 332 |
205 ASSERT(state == Pending); | 333 ASSERT(state == Pending || state == PendingWithResolvedFlagSet); |
206 if (!fulfillCallback.IsEmpty()) { | 334 if (!fulfillCallback.IsEmpty()) { |
207 v8::Local<v8::Array> callbacks = internal->GetInternalField(InternalFulf
illCallbackIndex).As<v8::Array>(); | 335 v8::Local<v8::Array> callbacks = internal->GetInternalField(InternalFulf
illCallbackIndex).As<v8::Array>(); |
208 callbacks->Set(callbacks->Length(), fulfillCallback); | 336 callbacks->Set(callbacks->Length(), fulfillCallback); |
209 } | 337 } |
210 if (!rejectCallback.IsEmpty()) { | 338 if (!rejectCallback.IsEmpty()) { |
211 v8::Local<v8::Array> callbacks = internal->GetInternalField(InternalReje
ctCallbackIndex).As<v8::Array>(); | 339 v8::Local<v8::Array> callbacks = internal->GetInternalField(InternalReje
ctCallbackIndex).As<v8::Array>(); |
212 callbacks->Set(callbacks->Length(), rejectCallback); | 340 callbacks->Set(callbacks->Length(), rejectCallback); |
213 } | 341 } |
214 } | 342 } |
215 | 343 |
(...skipping 22 matching lines...) Expand all Loading... |
238 internal->SetInternalField(V8PromiseCustom::InternalResultIndex, value); | 366 internal->SetInternalField(V8PromiseCustom::InternalResultIndex, value); |
239 internal->SetInternalField(V8PromiseCustom::InternalFulfillCallbackIndex, v8
::Array::New()); | 367 internal->SetInternalField(V8PromiseCustom::InternalFulfillCallbackIndex, v8
::Array::New()); |
240 internal->SetInternalField(V8PromiseCustom::InternalRejectCallbackIndex, v8:
:Array::New()); | 368 internal->SetInternalField(V8PromiseCustom::InternalRejectCallbackIndex, v8:
:Array::New()); |
241 } | 369 } |
242 | 370 |
243 V8PromiseCustom::PromiseState V8PromiseCustom::getState(v8::Handle<v8::Object> i
nternal) | 371 V8PromiseCustom::PromiseState V8PromiseCustom::getState(v8::Handle<v8::Object> i
nternal) |
244 { | 372 { |
245 v8::Handle<v8::Value> value = internal->GetInternalField(V8PromiseCustom::In
ternalStateIndex); | 373 v8::Handle<v8::Value> value = internal->GetInternalField(V8PromiseCustom::In
ternalStateIndex); |
246 bool ok = false; | 374 bool ok = false; |
247 uint32_t number = toInt32(value, ok); | 375 uint32_t number = toInt32(value, ok); |
248 ASSERT(ok && (number == Pending || number == Fulfilled || number == Rejected
)); | 376 ASSERT(ok && (number == Pending || number == Fulfilled || number == Rejected
|| number == PendingWithResolvedFlagSet)); |
249 return static_cast<PromiseState>(number); | 377 return static_cast<PromiseState>(number); |
250 } | 378 } |
251 | 379 |
252 void V8PromiseCustom::setState(v8::Handle<v8::Object> internal, PromiseState sta
te) | 380 void V8PromiseCustom::setState(v8::Handle<v8::Object> internal, PromiseState sta
te) |
253 { | 381 { |
254 ASSERT(state == Pending || state == Fulfilled || state == Rejected); | 382 ASSERT(state == Pending || state == Fulfilled || state == Rejected || state
== PendingWithResolvedFlagSet); |
255 internal->SetInternalField(V8PromiseCustom::InternalStateIndex, v8::Integer:
:New(state)); | 383 internal->SetInternalField(V8PromiseCustom::InternalStateIndex, v8::Integer:
:New(state)); |
256 } | 384 } |
257 | 385 |
258 void V8PromiseCustom::call(v8::Handle<v8::Function> function, v8::Handle<v8::Obj
ect> receiver, v8::Handle<v8::Value> result, SynchronousMode mode, v8::Isolate*
isolate) | 386 void V8PromiseCustom::call(v8::Handle<v8::Function> function, v8::Handle<v8::Obj
ect> receiver, v8::Handle<v8::Value> result, SynchronousMode mode, v8::Isolate*
isolate) |
259 { | 387 { |
260 if (mode == Synchronous) { | 388 if (mode == Synchronous) { |
261 v8::Context::Scope scope(isolate->GetCurrentContext()); | 389 v8::Context::Scope scope(isolate->GetCurrentContext()); |
262 // If an exception is thrown, catch it and do nothing. | 390 // If an exception is thrown, catch it and do nothing. |
263 v8::TryCatch trycatch; | 391 v8::TryCatch trycatch; |
264 v8::Handle<v8::Value> args[] = { result }; | 392 v8::Handle<v8::Value> args[] = { result }; |
265 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece
iver, WTF_ARRAY_LENGTH(args), args); | 393 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece
iver, WTF_ARRAY_LENGTH(args), args); |
266 } else { | 394 } else { |
267 ASSERT(mode == Asynchronous); | 395 ASSERT(mode == Asynchronous); |
268 postTask(function, receiver, result, isolate); | 396 postTask(function, receiver, result, isolate); |
269 } | 397 } |
270 } | 398 } |
271 | 399 |
272 } // namespace WebCore | 400 } // namespace WebCore |
OLD | NEW |