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; | 54 v8::Local<v8::Function> createClosure(v8::FunctionCallback function, v8::Handle< v8::Value> environment) |
abarth-chromium
2013/07/09 17:49:27
This seems like a really useful function. Perhaps
| |
55 int promiseResolveCallbackTag = 0; | |
56 int promiseRejectCallbackTag = 0; | |
57 | |
58 v8::Local<v8::Function> getFunction(v8::FunctionCallback callback, int* tag, v8: :Isolate* isolate) | |
59 { | 55 { |
60 // tag must be a pointer of one of the above tags. | 56 return v8::FunctionTemplate::New(function, environment)->GetFunction(); |
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 } | 57 } |
75 | 58 |
76 class PromiseTask : public ScriptExecutionContext::Task { | 59 class PromiseTask : public ScriptExecutionContext::Task { |
77 public: | 60 public: |
78 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv er, v8::Handle<v8::Value> result) | 61 PromiseTask(v8::Handle<v8::Function> callback, v8::Handle<v8::Object> receiv er, v8::Handle<v8::Value> result) |
79 : m_callback(callback) | 62 : m_callback(callback) |
80 , m_receiver(receiver) | 63 , m_receiver(receiver) |
81 , m_result(result) | 64 , m_result(result) |
82 { | 65 { |
83 ASSERT(!m_callback.isEmpty()); | 66 ASSERT(!m_callback.isEmpty()); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
149 // FIXME: v8::ObjectTemplate::New should be cached. | 132 // FIXME: v8::ObjectTemplate::New should be cached. |
150 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); | 133 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); |
151 objectTemplate->SetInternalFieldCount(V8PromiseCustom::WrapperCallbackEnviro nmentFieldCount); | 134 objectTemplate->SetInternalFieldCount(V8PromiseCustom::WrapperCallbackEnviro nmentFieldCount); |
152 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); | 135 v8::Local<v8::Object> environment = objectTemplate->NewInstance(); |
153 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentPro miseIndex, promise); | 136 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentPro miseIndex, promise); |
154 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentPro miseResolverIndex, resolver); | 137 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentPro miseResolverIndex, resolver); |
155 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentCal lbackIndex, callback); | 138 environment->SetInternalField(V8PromiseCustom::WrapperCallbackEnvironmentCal lbackIndex, callback); |
156 return environment; | 139 return environment; |
157 } | 140 } |
158 | 141 |
159 // This function must have the resolver as the first argument when called. | |
160 // See promiseCallback. | |
161 void promiseFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& args) | 142 void promiseFulfillCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
162 { | 143 { |
163 v8::Local<v8::Object> resolver; | 144 ASSERT(!args.Data().IsEmpty()); |
145 v8::Local<v8::Object> resolver = args.Data().As<v8::Object>(); | |
164 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); | 146 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
165 ASSERT(args.Length() > 0); | 147 if (args.Length() > 0) |
166 resolver = args[0].As<v8::Object>(); | 148 result = args[0]; |
167 if (args.Length() > 1) | |
168 result = args[1]; | |
169 | 149 |
170 V8PromiseCustom::fulfillResolver(resolver, result, V8PromiseCustom::Synchron ous, args.GetIsolate()); | 150 V8PromiseCustom::fulfillResolver(resolver, result, V8PromiseCustom::Synchron ous, args.GetIsolate()); |
171 } | 151 } |
172 | 152 |
173 // This function must have the resolver as the first argument when called. | |
174 // See promiseCallback. | |
175 void promiseResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) | 153 void promiseResolveCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
176 { | 154 { |
177 v8::Local<v8::Object> resolver; | 155 ASSERT(!args.Data().IsEmpty()); |
156 v8::Local<v8::Object> resolver = args.Data().As<v8::Object>(); | |
178 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); | 157 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
179 ASSERT(args.Length() > 0); | 158 if (args.Length() > 0) |
180 resolver = args[0].As<v8::Object>(); | 159 result = args[0]; |
181 if (args.Length() > 1) | |
182 result = args[1]; | |
183 | 160 |
184 V8PromiseCustom::resolveResolver(resolver, result, V8PromiseCustom::Synchron ous, args.GetIsolate()); | 161 V8PromiseCustom::resolveResolver(resolver, result, V8PromiseCustom::Synchron ous, args.GetIsolate()); |
185 } | 162 } |
186 | 163 |
187 // This function must have the resolver as the first argument when called. | |
188 // See promiseCallback. | |
189 void promiseRejectCallback(const v8::FunctionCallbackInfo<v8::Value>& args) | 164 void promiseRejectCallback(const v8::FunctionCallbackInfo<v8::Value>& args) |
190 { | 165 { |
191 v8::Local<v8::Object> resolver; | 166 ASSERT(!args.Data().IsEmpty()); |
167 v8::Local<v8::Object> resolver = args.Data().As<v8::Object>(); | |
192 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); | 168 v8::Local<v8::Value> result = v8::Undefined(args.GetIsolate()); |
193 ASSERT(args.Length() > 0); | 169 if (args.Length() > 0) |
194 resolver = args[0].As<v8::Object>(); | 170 result = args[0]; |
195 if (args.Length() > 1) | |
196 result = args[1]; | |
197 | 171 |
198 V8PromiseCustom::rejectResolver(resolver, result, V8PromiseCustom::Synchrono us, args.GetIsolate()); | 172 V8PromiseCustom::rejectResolver(resolver, result, V8PromiseCustom::Synchrono us, args.GetIsolate()); |
199 } | 173 } |
200 | 174 |
201 v8::Local<v8::Function> promiseCallback(v8::Handle<v8::Object> resolver, V8Promi seCustom::PromiseAlgorithm algorithm, v8::Isolate* isolate) | |
202 { | |
203 v8::Local<v8::Function> callback; | |
204 switch (algorithm) { | |
205 case V8PromiseCustom::FulfillAlgorithm: | |
206 callback = getFunction(promiseFulfillCallback, &promiseFulfillCallbackTa g, isolate); | |
207 break; | |
208 case V8PromiseCustom::ResolveAlgorithm: | |
209 callback = getFunction(promiseResolveCallback, &promiseResolveCallbackTa g, isolate); | |
210 break; | |
211 case V8PromiseCustom::RejectAlgorithm: | |
212 callback = getFunction(promiseRejectCallback, &promiseRejectCallbackTag, isolate); | |
213 break; | |
214 default: | |
215 ASSERT(0); | |
216 } | |
217 // We bind |resolver| to promise{Fulfill, Resolve, Reject}Callback. | |
218 // | |
219 // promiseCallback(result) will be evaluated as | |
220 // promiseFulfillCallback(resolver, result), | |
221 // if algorithm is FulfillAlgorithm. | |
222 | |
223 // FIXME: If there is a way to bind an object to a function other than evalu ate a JavaScript, it will be preferable. | |
224 // We should not depend on the global context that user can change, such as accessing a property, calling a method or so. | |
225 v8::Local<v8::String> script = v8String("(function(f, v1) { return function( v2) { return f(v1, v2); }; })", isolate); | |
226 v8::Local<v8::Value> value = V8ScriptRunner::compileAndRunInternalScript(scr ipt, isolate); | |
227 ASSERT(!value.IsEmpty()); | |
228 | |
229 v8::Local<v8::Value> argv[] = { | |
230 callback, | |
231 resolver, | |
232 }; | |
233 v8::Local<v8::Object> receiver = isolate->GetCurrentContext()->Global(); | |
234 | |
235 value = V8ScriptRunner::callFunction(value.As<v8::Function>(), getScriptExec utionContext(), receiver, WTF_ARRAY_LENGTH(argv), argv); | |
236 ASSERT(!value.IsEmpty()); | |
237 return value.As<v8::Function>(); | |
238 } | |
239 | |
240 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result , V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) | 175 void callCallbacks(v8::Handle<v8::Array> callbacks, v8::Handle<v8::Value> result , V8PromiseCustom::SynchronousMode mode, v8::Isolate* isolate) |
241 { | 176 { |
242 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); | 177 v8::Local<v8::Object> global = isolate->GetCurrentContext()->Global(); |
243 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { | 178 for (uint32_t i = 0, length = callbacks->Length(); i < length; ++i) { |
244 v8::Local<v8::Value> value = callbacks->Get(i); | 179 v8::Local<v8::Value> value = callbacks->Get(i); |
245 v8::Local<v8::Function> callback = value.As<v8::Function>(); | 180 v8::Local<v8::Function> callback = value.As<v8::Function>(); |
246 V8PromiseCustom::call(callback, global, result, mode, isolate); | 181 V8PromiseCustom::call(callback, global, result, mode, isolate); |
247 } | 182 } |
248 } | 183 } |
249 | 184 |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
341 { | 276 { |
342 v8::Isolate* isolate = args.GetIsolate(); | 277 v8::Isolate* isolate = args.GetIsolate(); |
343 v8::Local<v8::Function> fulfillWrapper, rejectWrapper; | 278 v8::Local<v8::Function> fulfillWrapper, rejectWrapper; |
344 v8::Local<v8::Object> promise, resolver; | 279 v8::Local<v8::Object> promise, resolver; |
345 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 280 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
346 if (args.Length() > 0 && !args[0]->IsUndefined()) { | 281 if (args.Length() > 0 && !args[0]->IsUndefined()) { |
347 if (!args[0]->IsFunction()) { | 282 if (!args[0]->IsFunction()) { |
348 v8SetReturnValue(args, throwTypeError("fulfillCallback must be a fun ction or undefined", isolate)); | 283 v8SetReturnValue(args, throwTypeError("fulfillCallback must be a fun ction or undefined", isolate)); |
349 return; | 284 return; |
350 } | 285 } |
351 v8::Local<v8::Object> environment = wrapperCallbackEnvironment(promise, resolver, args[0].As<v8::Function>()); | 286 fulfillWrapper = createClosure(wrapperCallback, wrapperCallbackEnvironme nt(promise, resolver, args[0].As<v8::Function>())); |
352 fulfillWrapper = v8::FunctionTemplate::New(wrapperCallback, environment) ->GetFunction(); | |
353 } else { | 287 } else { |
354 fulfillWrapper = promiseCallback(resolver, V8PromiseCustom::FulfillAlgor ithm, isolate); | 288 fulfillWrapper = createClosure(promiseFulfillCallback, resolver); |
355 } | 289 } |
356 if (args.Length() > 1 && !args[1]->IsUndefined()) { | 290 if (args.Length() > 1 && !args[1]->IsUndefined()) { |
357 if (!args[1]->IsFunction()) { | 291 if (!args[1]->IsFunction()) { |
358 v8SetReturnValue(args, throwTypeError("rejectCallback must be a func tion or undefined", isolate)); | 292 v8SetReturnValue(args, throwTypeError("rejectCallback must be a func tion or undefined", isolate)); |
359 return; | 293 return; |
360 } | 294 } |
361 v8::Local<v8::Object> environment = wrapperCallbackEnvironment(promise, resolver, args[1].As<v8::Function>()); | 295 rejectWrapper = createClosure(wrapperCallback, wrapperCallbackEnvironmen t(promise, resolver, args[1].As<v8::Function>())); |
362 rejectWrapper = v8::FunctionTemplate::New(wrapperCallback, environment)- >GetFunction(); | |
363 } else { | 296 } else { |
364 rejectWrapper = promiseCallback(resolver, V8PromiseCustom::RejectAlgorit hm, isolate); | 297 rejectWrapper = createClosure(promiseRejectCallback, resolver); |
365 } | 298 } |
366 V8PromiseCustom::append(args.Holder(), fulfillWrapper, rejectWrapper, isolat e); | 299 V8PromiseCustom::append(args.Holder(), fulfillWrapper, rejectWrapper, isolat e); |
367 v8SetReturnValue(args, promise); | 300 v8SetReturnValue(args, promise); |
368 } | 301 } |
369 | 302 |
370 void V8Promise::catchMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) | 303 void V8Promise::catchMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) |
371 { | 304 { |
372 v8::Isolate* isolate = args.GetIsolate(); | 305 v8::Isolate* isolate = args.GetIsolate(); |
373 v8::Local<v8::Function> fulfillWrapper, rejectWrapper; | 306 v8::Local<v8::Function> fulfillWrapper, rejectWrapper; |
374 v8::Local<v8::Object> promise, resolver; | 307 v8::Local<v8::Object> promise, resolver; |
375 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 308 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
376 | 309 |
377 if (args.Length() > 0 && !args[0]->IsUndefined()) { | 310 if (args.Length() > 0 && !args[0]->IsUndefined()) { |
378 if (!args[0]->IsFunction()) { | 311 if (!args[0]->IsFunction()) { |
379 v8SetReturnValue(args, throwTypeError("rejectCallback must be a func tion or undefined", isolate)); | 312 v8SetReturnValue(args, throwTypeError("rejectCallback must be a func tion or undefined", isolate)); |
380 return; | 313 return; |
381 } | 314 } |
382 v8::Local<v8::Object> environment = wrapperCallbackEnvironment(promise, resolver, args[0].As<v8::Function>()); | 315 rejectWrapper = createClosure(wrapperCallback, wrapperCallbackEnvironmen t(promise, resolver, args[0].As<v8::Function>())); |
383 rejectWrapper = v8::FunctionTemplate::New(wrapperCallback, environment)- >GetFunction(); | |
384 } else { | 316 } else { |
385 rejectWrapper = promiseCallback(resolver, V8PromiseCustom::RejectAlgorit hm, isolate); | 317 rejectWrapper = createClosure(promiseRejectCallback, resolver); |
386 } | 318 } |
387 fulfillWrapper = promiseCallback(resolver, V8PromiseCustom::FulfillAlgorithm , isolate); | 319 fulfillWrapper = createClosure(promiseFulfillCallback, resolver); |
388 V8PromiseCustom::append(args.Holder(), fulfillWrapper, rejectWrapper, isolat e); | 320 V8PromiseCustom::append(args.Holder(), fulfillWrapper, rejectWrapper, isolat e); |
389 v8SetReturnValue(args, promise); | 321 v8SetReturnValue(args, promise); |
390 } | 322 } |
391 | 323 |
392 void V8Promise::anyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& args) | 324 void V8Promise::anyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& args) |
393 { | 325 { |
394 v8::Isolate* isolate = args.GetIsolate(); | 326 v8::Isolate* isolate = args.GetIsolate(); |
395 v8::Local<v8::Object> promise, resolver; | 327 v8::Local<v8::Object> promise, resolver; |
396 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 328 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
397 | 329 |
398 if (!args.Length()) { | 330 if (!args.Length()) { |
399 V8PromiseCustom::resolveResolver(resolver, v8::Undefined(isolate), V8Pro miseCustom::Asynchronous, isolate); | 331 V8PromiseCustom::resolveResolver(resolver, v8::Undefined(isolate), V8Pro miseCustom::Asynchronous, isolate); |
400 v8SetReturnValue(args, promise); | 332 v8SetReturnValue(args, promise); |
401 return; | 333 return; |
402 } | 334 } |
403 | 335 |
404 v8::Local<v8::Function> fulfillCallback = promiseCallback(resolver, V8Promis eCustom::ResolveAlgorithm, isolate); | 336 v8::Local<v8::Function> fulfillCallback = createClosure(promiseResolveCallba ck, resolver); |
405 v8::Local<v8::Function> rejectCallback = promiseCallback(resolver, V8Promise Custom::RejectAlgorithm, isolate); | 337 v8::Local<v8::Function> rejectCallback = createClosure(promiseRejectCallback , resolver); |
406 | 338 |
407 for (int i = 0; i < args.Length(); ++i) { | 339 for (int i = 0; i < args.Length(); ++i) { |
408 v8::Local<v8::Object> eachPromise, eachResolver; | 340 v8::Local<v8::Object> eachPromise, eachResolver; |
409 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); | 341 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); |
410 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); | 342 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); |
411 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); | 343 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); |
412 } | 344 } |
413 v8SetReturnValue(args, promise); | 345 v8SetReturnValue(args, promise); |
414 } | 346 } |
415 | 347 |
416 void V8Promise::everyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) | 348 void V8Promise::everyMethodCustom(const v8::FunctionCallbackInfo<v8::Value>& arg s) |
417 { | 349 { |
418 v8::Isolate* isolate = args.GetIsolate(); | 350 v8::Isolate* isolate = args.GetIsolate(); |
419 v8::Local<v8::Object> promise, resolver; | 351 v8::Local<v8::Object> promise, resolver; |
420 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); | 352 V8PromiseCustom::createPromise(args.Holder(), &promise, &resolver, isolate); |
421 | 353 |
422 if (!args.Length()) { | 354 if (!args.Length()) { |
423 V8PromiseCustom::resolveResolver(resolver, v8::Undefined(isolate), V8Pro miseCustom::Asynchronous, isolate); | 355 V8PromiseCustom::resolveResolver(resolver, v8::Undefined(isolate), V8Pro miseCustom::Asynchronous, isolate); |
424 v8SetReturnValue(args, promise); | 356 v8SetReturnValue(args, promise); |
425 return; | 357 return; |
426 } | 358 } |
427 | 359 |
428 // FIXME: v8::ObjectTemplate::New should be cached. | 360 // FIXME: v8::ObjectTemplate::New should be cached. |
429 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); | 361 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); |
430 objectTemplate->SetInternalFieldCount(V8PromiseCustom::PrimitiveWrapperField Count); | 362 objectTemplate->SetInternalFieldCount(V8PromiseCustom::PrimitiveWrapperField Count); |
431 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); | 363 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); |
432 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv eIndex, v8::Integer::New(args.Length())); | 364 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv eIndex, v8::Integer::New(args.Length())); |
433 v8::Local<v8::Array> results = v8::Array::New(); | 365 v8::Local<v8::Array> results = v8::Array::New(); |
434 | 366 |
435 v8::Local<v8::Function> rejectCallback = promiseCallback(resolver, V8Promise Custom::RejectAlgorithm, isolate); | 367 v8::Local<v8::Function> rejectCallback = createClosure(promiseRejectCallback , resolver); |
436 for (int i = 0; i < args.Length(); ++i) { | 368 for (int i = 0; i < args.Length(); ++i) { |
437 v8::Local<v8::Object> environment = promiseEveryEnvironment(resolver, co untdownWrapper, i, results, isolate); | 369 v8::Local<v8::Object> environment = promiseEveryEnvironment(resolver, co untdownWrapper, i, results, isolate); |
438 v8::Local<v8::Function> fulfillCallback = v8::FunctionTemplate::New(prom iseEveryFulfillCallback, environment)->GetFunction(); | 370 v8::Local<v8::Function> fulfillCallback = v8::FunctionTemplate::New(prom iseEveryFulfillCallback, environment)->GetFunction(); |
439 v8::Local<v8::Object> eachPromise, eachResolver; | 371 v8::Local<v8::Object> eachPromise, eachResolver; |
440 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); | 372 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); |
441 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); | 373 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); |
442 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); | 374 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); |
443 } | 375 } |
444 v8SetReturnValue(args, promise); | 376 v8SetReturnValue(args, promise); |
445 } | 377 } |
(...skipping 11 matching lines...) Expand all Loading... | |
457 } | 389 } |
458 | 390 |
459 // Promise.some also uses PromiseEveryEnvironment. | 391 // Promise.some also uses PromiseEveryEnvironment. |
460 // FIXME: v8::ObjectTemplate::New should be cached. | 392 // FIXME: v8::ObjectTemplate::New should be cached. |
461 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); | 393 v8::Local<v8::ObjectTemplate> objectTemplate = v8::ObjectTemplate::New(); |
462 objectTemplate->SetInternalFieldCount(V8PromiseCustom::PrimitiveWrapperField Count); | 394 objectTemplate->SetInternalFieldCount(V8PromiseCustom::PrimitiveWrapperField Count); |
463 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); | 395 v8::Local<v8::Object> countdownWrapper = objectTemplate->NewInstance(); |
464 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv eIndex, v8::Integer::New(args.Length())); | 396 countdownWrapper->SetInternalField(V8PromiseCustom::PrimitiveWrapperPrimitiv eIndex, v8::Integer::New(args.Length())); |
465 v8::Local<v8::Array> results = v8::Array::New(); | 397 v8::Local<v8::Array> results = v8::Array::New(); |
466 | 398 |
467 v8::Local<v8::Function> fulfillCallback = promiseCallback(resolver, V8Promis eCustom::ResolveAlgorithm, isolate); | 399 v8::Local<v8::Function> fulfillCallback = createClosure(promiseResolveCallba ck, resolver); |
468 for (int i = 0; i < args.Length(); ++i) { | 400 for (int i = 0; i < args.Length(); ++i) { |
469 v8::Local<v8::Object> environment = promiseEveryEnvironment(resolver, co untdownWrapper, i, results, isolate); | 401 v8::Local<v8::Object> environment = promiseEveryEnvironment(resolver, co untdownWrapper, i, results, isolate); |
470 v8::Local<v8::Object> eachPromise, eachResolver; | 402 v8::Local<v8::Object> eachPromise, eachResolver; |
471 v8::Local<v8::Function> rejectCallback = v8::FunctionTemplate::New(promi seSomeRejectCallback, environment)->GetFunction(); | 403 v8::Local<v8::Function> rejectCallback = v8::FunctionTemplate::New(promi seSomeRejectCallback, environment)->GetFunction(); |
472 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); | 404 V8PromiseCustom::createPromise(args.Holder(), &eachPromise, &eachResolve r, isolate); |
473 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); | 405 V8PromiseCustom::resolveResolver(eachResolver, args[i], V8PromiseCustom: :Asynchronous, isolate); |
474 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); | 406 V8PromiseCustom::append(eachPromise, fulfillCallback, rejectCallback, is olate); |
475 } | 407 } |
476 v8SetReturnValue(args, promise); | 408 v8SetReturnValue(args, promise); |
477 } | 409 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
517 // If calling the [[Get]] internal method threw an exception, catch it and run reject. | 449 // If calling the [[Get]] internal method threw an exception, catch it and run reject. |
518 rejectResolver(resolver, trycatch.Exception(), mode, isolate); | 450 rejectResolver(resolver, trycatch.Exception(), mode, isolate); |
519 return; | 451 return; |
520 } | 452 } |
521 } | 453 } |
522 | 454 |
523 if (!then.IsEmpty() && then->IsFunction()) { | 455 if (!then.IsEmpty() && then->IsFunction()) { |
524 ASSERT(result->IsObject()); | 456 ASSERT(result->IsObject()); |
525 v8::TryCatch trycatch; | 457 v8::TryCatch trycatch; |
526 v8::Handle<v8::Value> argv[] = { | 458 v8::Handle<v8::Value> argv[] = { |
527 promiseCallback(resolver, ResolveAlgorithm, isolate), | 459 createClosure(promiseResolveCallback, resolver), |
528 promiseCallback(resolver, RejectAlgorithm, isolate), | 460 createClosure(promiseRejectCallback, resolver), |
529 }; | 461 }; |
530 if (V8ScriptRunner::callFunction(then.As<v8::Function>(), getScriptExecu tionContext(), result.As<v8::Object>(), WTF_ARRAY_LENGTH(argv), argv).IsEmpty()) | 462 if (V8ScriptRunner::callFunction(then.As<v8::Function>(), getScriptExecu tionContext(), result.As<v8::Object>(), WTF_ARRAY_LENGTH(argv), argv).IsEmpty()) |
531 rejectResolver(resolver, trycatch.Exception(), mode, isolate); | 463 rejectResolver(resolver, trycatch.Exception(), mode, isolate); |
532 return; | 464 return; |
533 } | 465 } |
534 | 466 |
535 fulfillResolver(resolver, result, mode, isolate); | 467 fulfillResolver(resolver, result, mode, isolate); |
536 } | 468 } |
537 | 469 |
538 void V8PromiseCustom::rejectResolver(v8::Handle<v8::Object> resolver, v8::Handle <v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) | 470 void V8PromiseCustom::rejectResolver(v8::Handle<v8::Object> resolver, v8::Handle <v8::Value> result, SynchronousMode mode, v8::Isolate* isolate) |
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
632 v8::TryCatch trycatch; | 564 v8::TryCatch trycatch; |
633 v8::Handle<v8::Value> args[] = { result }; | 565 v8::Handle<v8::Value> args[] = { result }; |
634 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece iver, WTF_ARRAY_LENGTH(args), args); | 566 V8ScriptRunner::callFunction(function, getScriptExecutionContext(), rece iver, WTF_ARRAY_LENGTH(args), args); |
635 } else { | 567 } else { |
636 ASSERT(mode == Asynchronous); | 568 ASSERT(mode == Asynchronous); |
637 postTask(function, receiver, result, isolate); | 569 postTask(function, receiver, result, isolate); |
638 } | 570 } |
639 } | 571 } |
640 | 572 |
641 } // namespace WebCore | 573 } // namespace WebCore |
OLD | NEW |