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