Chromium Code Reviews| 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 14 matching lines...) Expand all Loading... | |
| 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 29 */ | 29 */ |
| 30 | 30 |
| 31 #include "config.h" | 31 #include "config.h" |
| 32 #include "bindings/v8/custom/V8PromiseCustom.h" | 32 #include "bindings/v8/custom/V8PromiseCustom.h" |
| 33 | 33 |
| 34 #include "V8Promise.h" | 34 #include "V8Promise.h" |
| 35 #include "V8PromiseResolver.h" | |
| 36 #include "bindings/v8/ScopedPersistent.h" | 35 #include "bindings/v8/ScopedPersistent.h" |
| 37 #include "bindings/v8/ScriptFunctionCall.h" | 36 #include "bindings/v8/ScriptFunctionCall.h" |
| 38 #include "bindings/v8/ScriptState.h" | 37 #include "bindings/v8/ScriptState.h" |
| 39 #include "bindings/v8/V8Binding.h" | 38 #include "bindings/v8/V8Binding.h" |
| 40 #include "bindings/v8/V8PerIsolateData.h" | 39 #include "bindings/v8/V8PerIsolateData.h" |
| 41 #include "bindings/v8/V8ScriptRunner.h" | 40 #include "bindings/v8/V8ScriptRunner.h" |
| 42 #include "bindings/v8/WrapperTypeInfo.h" | 41 #include "bindings/v8/WrapperTypeInfo.h" |
| 43 #include "core/dom/Document.h" | 42 #include "core/dom/Document.h" |
| 44 #include "core/page/DOMWindow.h" | 43 #include "core/page/DOMWindow.h" |
| 45 #include "core/platform/Task.h" | 44 #include "core/platform/Task.h" |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 88 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prim itiveWrapperFieldCount, isolate); | 87 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prim itiveWrapperFieldCount, isolate); |
| 89 } | 88 } |
| 90 | 89 |
| 91 v8::Local<v8::ObjectTemplate> internalObjectTemplate(v8::Isolate* isolate) | 90 v8::Local<v8::ObjectTemplate> internalObjectTemplate(v8::Isolate* isolate) |
| 92 { | 91 { |
| 93 // This is only for getting a unique pointer which we can pass to privateTem plate. | 92 // This is only for getting a unique pointer which we can pass to privateTem plate. |
| 94 static int privateTemplateUniqueKey = 0; | 93 static int privateTemplateUniqueKey = 0; |
| 95 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Inte rnalFieldCount, isolate); | 94 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Inte rnalFieldCount, isolate); |
| 96 } | 95 } |
| 97 | 96 |
| 97 v8::Local<v8::ObjectTemplate> resolverObjectTemplate(v8::Isolate* isolate) | |
| 98 { | |
| 99 // This is only for getting a unique pointer which we can pass to privateTem plate. | |
| 100 static int privateTemplateUniqueKey = 0; | |
| 101 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Reso lverFieldCount, isolate); | |
| 102 } | |
| 103 | |
| 98 class PromiseTask : public ScriptExecutionContext::Task { | 104 class PromiseTask : public ScriptExecutionContext::Task { |
| 99 public: | 105 public: |
| 100 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv er, v8::Handle<v8::Value> result, v8::Isolate* isolate) | 106 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv er, v8::Handle<v8::Value> result, v8::Isolate* isolate) |
| 101 : m_callback(isolate, callback) | 107 : m_callback(isolate, callback) |
| 102 , m_receiver(isolate, receiver) | 108 , m_receiver(isolate, receiver) |
| 103 , m_result(isolate, result) | 109 , m_result(isolate, result) |
| 104 { | 110 { |
| 105 ASSERT(!m_callback.isEmpty()); | 111 ASSERT(!m_callback.isEmpty()); |
| 106 ASSERT(!m_receiver.isEmpty()); | 112 ASSERT(!m_receiver.isEmpty()); |
| 107 ASSERT(!m_result.isEmpty()); | 113 ASSERT(!m_result.isEmpty()); |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 280 v8::Local<v8::ObjectTemplate> objectTemplate = promiseEveryEnvironmentObject Template(isolate); | 286 v8::Local<v8::ObjectTemplate> objectTemplate = promiseEveryEnvironmentObject Template(isolate); |
| 281 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); | 287 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); |
| 282 | 288 |
| 283 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentPromis eResolverIndex, resolver); | 289 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentPromis eResolverIndex, resolver); |
| 284 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentCountd ownIndex, countdownWrapper); | 290 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentCountd ownIndex, countdownWrapper); |
| 285 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentIndexI ndex, v8::Integer::New(index, isolate)); | 291 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentIndexI ndex, v8::Integer::New(index, isolate)); |
| 286 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentResult sIndex, results); | 292 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentResult sIndex, results); |
| 287 return environment; | 293 return environment; |
| 288 } | 294 } |
| 289 | 295 |
| 296 void promiseResolve(const v8::FunctionCallbackInfo<v8::Value>& args) | |
| 297 { | |
| 298 v8::Local<v8::Object> resolver = args.Data().As<v8::Object>(); | |
| 299 ASSERT(!resolver.IsEmpty()); | |
| 300 if (V8PromiseCustom::isInternalDetached(resolver)) | |
| 301 return; | |
| 302 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(resolver); | |
| 303 if (V8PromiseCustom::getState(internal) != V8PromiseCustom::Pending) | |
| 304 return; | |
| 305 v8::Isolate* isolate = args.GetIsolate(); | |
| 306 V8PromiseCustom::setState(internal, V8PromiseCustom::PendingWithResolvedFlag Set, isolate); | |
| 307 | |
| 308 v8::Local<v8::Value> result = v8::Undefined(isolate); | |
| 309 if (args.Length() > 0) | |
| 310 result = args[0]; | |
| 311 V8PromiseCustom::resolveResolver(resolver, result, V8PromiseCustom::Asynchro nous, isolate); | |
| 312 } | |
| 313 | |
| 314 void promiseReject(const v8::FunctionCallbackInfo<v8::Value>& args) | |
| 315 { | |
| 316 v8::Local<v8::Object> resolver = args.Data().As<v8::Object>(); | |
| 317 ASSERT(!resolver.IsEmpty()); | |
| 318 if (V8PromiseCustom::isInternalDetached(resolver)) | |
| 319 return; | |
| 320 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(resolver); | |
| 321 if (V8PromiseCustom::getState(internal) != V8PromiseCustom::Pending) | |
| 322 return; | |
| 323 v8::Isolate* isolate = args.GetIsolate(); | |
| 324 V8PromiseCustom::setState(internal, V8PromiseCustom::PendingWithResolvedFlag Set, isolate); | |
| 325 | |
| 326 v8::Local<v8::Value> result = v8::Undefined(isolate); | |
| 327 if (args.Length() > 0) | |
| 328 result = args[0]; | |
| 329 V8PromiseCustom::rejectResolver(resolver, result, V8PromiseCustom::Asynchron ous, isolate); | |
| 330 } | |
| 331 | |
| 290 } // namespace | 332 } // namespace |
| 291 | 333 |
| 292 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) | 334 void V8Promise::constructorCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) |
| 293 { | 335 { |
| 294 v8SetReturnValue(args, v8::Local<v8::Value>()); | 336 v8SetReturnValue(args, v8::Local<v8::Value>()); |
| 295 v8::Isolate* isolate = args.GetIsolate(); | 337 v8::Isolate* isolate = args.GetIsolate(); |
| 296 if (!args.Length() || !args[0]->IsFunction()) { | 338 if (!args.Length() || !args[0]->IsFunction()) { |
| 297 throwTypeError("Promise constructor takes a function argument", isolate) ; | 339 throwTypeError("Promise constructor takes a function argument", isolate) ; |
| 298 return; | 340 return; |
| 299 } | 341 } |
| 300 v8::Local<v8::Function> init = args[0].As<v8::Function>(); | 342 v8::Local<v8::Function> init = args[0].As<v8::Function>(); |
| 301 v8::Local<v8::Object> promise, resolver; | 343 v8::Local<v8::Object> promise, resolver; |
| 302 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 344 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
| 303 v8::Handle<v8::Value> argv[] = { | 345 v8::Handle<v8::Value> argv[] = { |
| 304 resolver, | 346 createClosure(promiseResolve, resolver), |
| 347 createClosure(promiseReject, resolver) | |
| 305 }; | 348 }; |
| 306 v8::TryCatch trycatch; | 349 v8::TryCatch trycatch; |
| 307 if (V8ScriptRunner::callFunction(init, getScriptExecutionContext(), promise, WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) { | 350 if (V8ScriptRunner::callFunction(init, getScriptExecutionContext(), promise, WTF_ARRAY_LENGTH(argv), argv, isolate).IsEmpty()) { |
| 308 // An exception is thrown. Reject the promise if its resolved flag is un set. | 351 // An exception is thrown. Reject the promise if its resolved flag is un set. |
| 309 if (!V8PromiseCustom::isInternalDetached(resolver) && V8PromiseCustom::g etState(V8PromiseCustom::getInternal(resolver)) == V8PromiseCustom::Pending) | 352 if (!V8PromiseCustom::isInternalDetached(resolver) && V8PromiseCustom::g etState(V8PromiseCustom::getInternal(resolver)) == V8PromiseCustom::Pending) |
| 310 V8PromiseCustom::rejectResolver(resolver, trycatch.Exception(), V8Pr omiseCustom::Asynchronous, isolate); | 353 V8PromiseCustom::rejectResolver(resolver, trycatch.Exception(), V8Pr omiseCustom::Asynchronous, isolate); |
| 311 } | 354 } |
| 312 v8SetReturnValue(args, promise); | 355 v8SetReturnValue(args, promise); |
| 313 return; | 356 return; |
| 314 } | 357 } |
| (...skipping 167 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 482 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); | 525 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); |
| 483 } | 526 } |
| 484 v8SetReturnValue(args, promise); | 527 v8SetReturnValue(args, promise); |
| 485 } | 528 } |
| 486 | 529 |
| 487 // | 530 // |
| 488 // -- V8PromiseCustom -- | 531 // -- V8PromiseCustom -- |
| 489 void V8PromiseCustom::createPromise(v8::Handle<v8::Object> creationContext, v8:: Local<v8::Object>* promise, v8::Local<v8::Object>* resolver, v8::Isolate* isolat e) | 532 void V8PromiseCustom::createPromise(v8::Handle<v8::Object> creationContext, v8:: Local<v8::Object>* promise, v8::Local<v8::Object>* resolver, v8::Isolate* isolat e) |
| 490 { | 533 { |
| 491 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol ate); | 534 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol ate); |
| 535 v8::Local<v8::ObjectTemplate> resolverTemplate = resolverObjectTemplate(isol ate); | |
| 492 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); | 536 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); |
| 537 *resolver = resolverTemplate->NewInstance(); | |
| 493 *promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::info, 0, isolate); | 538 *promise = V8DOMWrapper::createWrapper(creationContext, &V8Promise::info, 0, isolate); |
| 494 *resolver = V8DOMWrapper::createWrapper(creationContext, &V8PromiseResolver: :info, 0, isolate); | |
| 495 | 539 |
| 496 clearInternal(internal, V8PromiseCustom::Pending, v8::Undefined(isolate), is olate); | 540 clearInternal(internal, V8PromiseCustom::Pending, v8::Undefined(isolate), is olate); |
| 497 | 541 |
| 498 (*promise)->SetInternalField(v8DOMWrapperObjectIndex, internal); | 542 (*promise)->SetInternalField(v8DOMWrapperObjectIndex, internal); |
| 499 (*resolver)->SetInternalField(v8DOMWrapperObjectIndex, internal); | 543 (*resolver)->SetInternalField(v8DOMWrapperObjectIndex, internal); |
|
yhirano
2013/09/18 12:52:39
Please add a comment describing that v8DOMWrapperO
yusukesuzuki
2013/09/18 14:48:24
Done.
| |
| 500 } | 544 } |
| 501 | 545 |
| 502 void V8PromiseCustom::fulfillResolver(v8::Handle<v8::Object> resolver, v8::Handl e<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) | 546 void V8PromiseCustom::fulfillResolver(v8::Handle<v8::Object> resolver, v8::Handl e<v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) |
| 503 { | 547 { |
| 504 if (isInternalDetached(resolver)) | 548 if (isInternalDetached(resolver)) |
| 505 return; | 549 return; |
| 506 v8::Local<v8::Object> internal = getInternal(resolver); | 550 v8::Local<v8::Object> internal = getInternal(resolver); |
| 507 ASSERT(getState(internal) == Pending || getState(internal) == PendingWithRes olvedFlagSet); | 551 ASSERT(getState(internal) == Pending || getState(internal) == PendingWithRes olvedFlagSet); |
| 508 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom: :InternalFulfillCallbackIndex).As<v8::Array>(); | 552 v8::Local<v8::Array> callbacks = internal->GetInternalField(V8PromiseCustom: :InternalFulfillCallbackIndex).As<v8::Array>(); |
| 509 clearInternal(internal, Fulfilled, result, isolate); | 553 clearInternal(internal, Fulfilled, result, isolate); |
| (...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 638 v8::TryCatch trycatch; | 682 v8::TryCatch trycatch; |
| 639 v8::Handle<v8::Value> args[] = { result }; | 683 v8::Handle<v8::Value> args[] = { result }; |
| 640 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece iver, WTF_ARRAY_LENGTH(args), args, isolate); | 684 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece iver, WTF_ARRAY_LENGTH(args), args, isolate); |
| 641 } else { | 685 } else { |
| 642 ASSERT(mode == Asynchronous); | 686 ASSERT(mode == Asynchronous); |
| 643 postTask(function, receiver, result, isolate); | 687 postTask(function, receiver, result, isolate); |
| 644 } | 688 } |
| 645 } | 689 } |
| 646 | 690 |
| 647 } // namespace WebCore | 691 } // namespace WebCore |
| OLD | NEW |