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