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 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 |