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 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
66 return instanceTemplate; | 66 return instanceTemplate; |
67 } | 67 } |
68 | 68 |
69 v8::Local<v8::ObjectTemplate> wrapperCallbackEnvironmentObjectTemplate(v8::Isola
te* isolate) | 69 v8::Local<v8::ObjectTemplate> wrapperCallbackEnvironmentObjectTemplate(v8::Isola
te* isolate) |
70 { | 70 { |
71 // This is only for getting a unique pointer which we can pass to privateTem
plate. | 71 // This is only for getting a unique pointer which we can pass to privateTem
plate. |
72 static int privateTemplateUniqueKey = 0; | 72 static int privateTemplateUniqueKey = 0; |
73 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Wrap
perCallbackEnvironmentFieldCount, isolate); | 73 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Wrap
perCallbackEnvironmentFieldCount, isolate); |
74 } | 74 } |
75 | 75 |
76 v8::Local<v8::ObjectTemplate> promiseEveryEnvironmentObjectTemplate(v8::Isolate*
isolate) | 76 v8::Local<v8::ObjectTemplate> promiseAllEnvironmentObjectTemplate(v8::Isolate* i
solate) |
77 { | 77 { |
78 // This is only for getting a unique pointer which we can pass to privateTem
plate. | 78 // This is only for getting a unique pointer which we can pass to privateTem
plate. |
79 static int privateTemplateUniqueKey = 0; | 79 static int privateTemplateUniqueKey = 0; |
80 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prom
iseEveryEnvironmentFieldCount, isolate); | 80 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prom
iseAllEnvironmentFieldCount, isolate); |
81 } | 81 } |
82 | 82 |
83 v8::Local<v8::ObjectTemplate> primitiveWrapperObjectTemplate(v8::Isolate* isolat
e) | 83 v8::Local<v8::ObjectTemplate> primitiveWrapperObjectTemplate(v8::Isolate* isolat
e) |
84 { | 84 { |
85 // This is only for getting a unique pointer which we can pass to privateTem
plate. | 85 // This is only for getting a unique pointer which we can pass to privateTem
plate. |
86 static int privateTemplateUniqueKey = 0; | 86 static int privateTemplateUniqueKey = 0; |
87 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prim
itiveWrapperFieldCount, isolate); | 87 return cachedObjectTemplate(&privateTemplateUniqueKey, V8PromiseCustom::Prim
itiveWrapperFieldCount, isolate); |
88 } | 88 } |
89 | 89 |
90 v8::Local<v8::ObjectTemplate> internalObjectTemplate(v8::Isolate* isolate) | 90 v8::Local<v8::ObjectTemplate> internalObjectTemplate(v8::Isolate* isolate) |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
215 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result
, V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) | 215 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result
, V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) |
216 { | 216 { |
217 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); | 217 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); |
218 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { | 218 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { |
219 v8::Local<v8::Value> value = callbacks->Get(i); | 219 v8::Local<v8::Value> value = callbacks->Get(i); |
220 v8::Local<v8::Function> callback = value.As<v8::Function>(); | 220 v8::Local<v8::Function> callback = value.As<v8::Function>(); |
221 V8PromiseCustom::call(callback, global, result, mode, isolate); | 221 V8PromiseCustom::call(callback, global, result, mode, isolate); |
222 } | 222 } |
223 } | 223 } |
224 | 224 |
225 void promiseEveryFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& args
) | 225 void promiseAllFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
226 { | 226 { |
227 v8::Isolate* isolate = args.GetIsolate(); | 227 v8::Isolate* isolate = args.GetIsolate(); |
228 ASSERT(!args.Data().IsEmpty()); | 228 ASSERT(!args.Data().IsEmpty()); |
229 v8::Local<v8::Object> environment = args.Data().As<v8::Object>(); | 229 v8::Local<v8::Object> environment = args.Data().As<v8::Object>(); |
230 v8::Local<v8::Value> result = v8::Undefined(isolate); | 230 v8::Local<v8::Value> result = v8::Undefined(isolate); |
231 if (args.Length() > 0) | 231 if (args.Length() > 0) |
232 result = args[0]; | 232 result = args[0]; |
233 | 233 |
234 v8::Local<v8::Object> promise = environment->GetInternalField(V8PromiseCusto
m::PromiseEveryEnvironmentPromiseIndex).As<v8::Object>(); | 234 v8::Local<v8::Object> promise = environment->GetInternalField(V8PromiseCusto
m::PromiseAllEnvironmentPromiseIndex).As<v8::Object>(); |
235 v8::Local<v8::Object> countdownWrapper = environment->GetInternalField(V8Pro
miseCustom::PromiseEveryEnvironmentCountdownIndex).As<v8::Object>(); | 235 v8::Local<v8::Object> countdownWrapper = environment->GetInternalField(V8Pro
miseCustom::PromiseAllEnvironmentCountdownIndex).As<v8::Object>(); |
236 v8::Local<v8::Integer> index = environment->GetInternalField(V8PromiseCustom
::PromiseEveryEnvironmentIndexIndex).As<v8::Integer>(); | 236 v8::Local<v8::Integer> index = environment->GetInternalField(V8PromiseCustom
::PromiseAllEnvironmentIndexIndex).As<v8::Integer>(); |
237 v8::Local<v8::Array> results = environment->GetInternalField(V8PromiseCustom
::PromiseEveryEnvironmentResultsIndex).As<v8::Array>(); | 237 v8::Local<v8::Array> results = environment->GetInternalField(V8PromiseCustom
::PromiseAllEnvironmentResultsIndex).As<v8::Array>(); |
238 | 238 |
239 results->Set(index->Value(), result); | 239 results->Set(index->Value(), result); |
240 | 240 |
241 v8::Local<v8::Integer> countdown = countdownWrapper->GetInternalField(V8Prom
iseCustom::PrimitiveWrapperPrimitiveIndex).As<v8::Integer>(); | 241 v8::Local<v8::Integer> countdown = countdownWrapper->GetInternalField(V8Prom
iseCustom::PrimitiveWrapperPrimitiveIndex).As<v8::Integer>(); |
242 ASSERT(countdown->Value() >= 1); | 242 ASSERT(countdown->Value() >= 1); |
243 if (countdown->Value() == 1) { | 243 if (countdown->Value() == 1) { |
244 V8PromiseCustom::resolve(promise, results, V8PromiseCustom::Synchronous,
isolate); | 244 V8PromiseCustom::resolve(promise, results, V8PromiseCustom::Synchronous,
isolate); |
245 return; | 245 return; |
246 } | 246 } |
247 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv
eIndex, v8::Integer::New(countdown->Value() - 1, isolate)); | 247 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv
eIndex, v8::Integer::New(countdown->Value() - 1, isolate)); |
248 } | 248 } |
249 | 249 |
250 v8::Local<v8::Object> promiseEveryEnvironment(v8::Handle<v8::Object> promise, v8
::Handle<v8::Object> countdownWrapper, int index, v8::Handle<v8::Array> results,
v8::Isolate* isolate) | 250 v8::Local<v8::Object> promiseAllEnvironment(v8::Handle<v8::Object> promise, v8::
Handle<v8::Object> countdownWrapper, int index, v8::Handle<v8::Array> results, v
8::Isolate* isolate) |
251 { | 251 { |
252 v8::Local<v8::ObjectTemplate> objectTemplate = promiseEveryEnvironmentObject
Template(isolate); | 252 v8::Local<v8::ObjectTemplate> objectTemplate = promiseAllEnvironmentObjectTe
mplate(isolate); |
253 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); | 253 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); |
254 | 254 |
255 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentPromis
eIndex, promise); | 255 environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentPromiseI
ndex, promise); |
256 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentCountd
ownIndex, countdownWrapper); | 256 environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentCountdow
nIndex, countdownWrapper); |
257 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentIndexI
ndex, v8::Integer::New(index, isolate)); | 257 environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentIndexInd
ex, v8::Integer::New(index, isolate)); |
258 environment->SetInternalField(V8PromiseCustom::PromiseEveryEnvironmentResult
sIndex, results); | 258 environment->SetInternalField(V8PromiseCustom::PromiseAllEnvironmentResultsI
ndex, results); |
259 return environment; | 259 return environment; |
260 } | 260 } |
261 | 261 |
262 void promiseResolve(const v8::FunctionCallbackInfo<v8::Value>& args) | 262 void promiseResolve(const v8::FunctionCallbackInfo<v8::Value>& args) |
263 { | 263 { |
264 v8::Local<v8::Object> promise = args.Data().As<v8::Object>(); | 264 v8::Local<v8::Object> promise = args.Data().As<v8::Object>(); |
265 ASSERT(!promise.IsEmpty()); | 265 ASSERT(!promise.IsEmpty()); |
266 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); | 266 v8::Local<v8::Object> internal = V8PromiseCustom::getInternal(promise); |
267 if (V8PromiseCustom::getState(internal) != V8PromiseCustom::Pending) | 267 if (V8PromiseCustom::getState(internal) != V8PromiseCustom::Pending) |
268 return; | 268 return; |
(...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
415 | 415 |
416 for (unsigned i = 0, length = iterable->Length(); i < length; ++i) { | 416 for (unsigned i = 0, length = iterable->Length(); i < length; ++i) { |
417 // Array-holes should not be skipped by for-of iteration semantics. | 417 // Array-holes should not be skipped by for-of iteration semantics. |
418 V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i)); | 418 V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i)); |
419 v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue
, isolate); | 419 v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue
, isolate); |
420 V8PromiseCustom::append(nextPromise, fulfillCallback, rejectCallback, is
olate); | 420 V8PromiseCustom::append(nextPromise, fulfillCallback, rejectCallback, is
olate); |
421 } | 421 } |
422 v8SetReturnValue(args, promise); | 422 v8SetReturnValue(args, promise); |
423 } | 423 } |
424 | 424 |
425 void V8Promise::everyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& arg
s) | 425 void V8Promise::allMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& args) |
426 { | 426 { |
427 v8::Isolate* isolate = args.GetIsolate(); | 427 v8::Isolate* isolate = args.GetIsolate(); |
428 v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(args.Holder()
, isolate); | 428 v8::Local<v8::Object> promise = V8PromiseCustom::createPromise(args.Holder()
, isolate); |
| 429 v8::Local<v8::Array> results = v8::Array::New(); |
429 | 430 |
430 if (!args.Length()) { | 431 if (!args.Length() || !args[0]->IsArray()) { |
431 V8PromiseCustom::resolve(promise, v8::Undefined(isolate), V8PromiseCusto
m::Asynchronous, isolate); | 432 V8PromiseCustom::resolve(promise, results, V8PromiseCustom::Asynchronous
, isolate); |
| 433 v8SetReturnValue(args, promise); |
| 434 return; |
| 435 } |
| 436 |
| 437 // FIXME: Now we limit the iterable type to the Array type. |
| 438 v8::Local<v8::Array> iterable = args[0].As<v8::Array>(); |
| 439 |
| 440 if (!iterable->Length()) { |
| 441 V8PromiseCustom::resolve(promise, results, V8PromiseCustom::Asynchronous
, isolate); |
432 v8SetReturnValue(args, promise); | 442 v8SetReturnValue(args, promise); |
433 return; | 443 return; |
434 } | 444 } |
435 | 445 |
436 v8::Local<v8::ObjectTemplate> objectTemplate = primitiveWrapperObjectTemplat
e(isolate); | 446 v8::Local<v8::ObjectTemplate> objectTemplate = primitiveWrapperObjectTemplat
e(isolate); |
437 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); | 447 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); |
438 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv
eIndex, v8::Integer::New(args.Length(), isolate)); | 448 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv
eIndex, v8::Integer::New(iterable->Length(), isolate)); |
439 v8::Local<v8::Array> results = v8::Array::New(); | |
440 | 449 |
441 v8::Local<v8::Function> rejectCallback = createClosure(promiseRejectCallback
, promise, isolate); | 450 v8::Local<v8::Function> rejectCallback = createClosure(promiseRejectCallback
, promise, isolate); |
442 for (int i = 0; i < args.Length(); ++i) { | 451 for (unsigned i = 0, length = iterable->Length(); i < length; ++i) { |
443 v8::Local<v8::Object> environment = promiseEveryEnvironment(promise, cou
ntdownWrapper, i, results, isolate); | 452 // Array-holes should not be skipped by for-of iteration semantics. |
444 v8::Local<v8::Function> fulfillCallback = createClosure(promiseEveryFulf
illCallback, environment, isolate); | 453 v8::Local<v8::Object> environment = promiseAllEnvironment(promise, count
downWrapper, i, results, isolate); |
445 v8::Local<v8::Object> eachPromise = V8PromiseCustom::createPromise(args.
Holder(), isolate); | 454 v8::Local<v8::Function> fulfillCallback = createClosure(promiseAllFulfil
lCallback, environment, isolate); |
446 V8PromiseCustom::resolve(eachPromise, args[i], V8PromiseCustom::Asynchro
nous, isolate); | 455 V8TRYCATCH_VOID(v8::Local<v8::Value>, nextValue, iterable->Get(i)); |
447 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is
olate); | 456 v8::Local<v8::Object> nextPromise = V8PromiseCustom::toPromise(nextValue
, isolate); |
| 457 V8PromiseCustom::append(nextPromise, fulfillCallback, rejectCallback, is
olate); |
448 } | 458 } |
449 v8SetReturnValue(args, promise); | 459 v8SetReturnValue(args, promise); |
450 } | 460 } |
451 | 461 |
452 // | 462 // |
453 // -- V8PromiseCustom -- | 463 // -- V8PromiseCustom -- |
454 v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> crea
tionContext, v8::Isolate* isolate) | 464 v8::Local<v8::Object> V8PromiseCustom::createPromise(v8::Handle<v8::Object> crea
tionContext, v8::Isolate* isolate) |
455 { | 465 { |
456 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol
ate); | 466 v8::Local<v8::ObjectTemplate> internalTemplate = internalObjectTemplate(isol
ate); |
457 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); | 467 v8::Local<v8::Object> internal = internalTemplate->NewInstance(); |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
611 // constructor. | 621 // constructor. |
612 if (isPromise(maybePromise, isolate)) | 622 if (isPromise(maybePromise, isolate)) |
613 return maybePromise.As<v8::Object>(); | 623 return maybePromise.As<v8::Object>(); |
614 | 624 |
615 v8::Local<v8::Object> promise = createPromise(v8::Handle<v8::Object>(), isol
ate); | 625 v8::Local<v8::Object> promise = createPromise(v8::Handle<v8::Object>(), isol
ate); |
616 resolve(promise, maybePromise, Asynchronous, isolate); | 626 resolve(promise, maybePromise, Asynchronous, isolate); |
617 return promise; | 627 return promise; |
618 } | 628 } |
619 | 629 |
620 } // namespace WebCore | 630 } // namespace WebCore |
OLD | NEW |