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