Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(8)

Side by Side Diff: src/promise.js

Issue 99573002: Promises: some adaptations to spec (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Dmitry's comments Created 7 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/messages.js ('k') | src/runtime.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
53 var promiseStatus = NEW_PRIVATE("Promise#status"); 53 var promiseStatus = NEW_PRIVATE("Promise#status");
54 var promiseValue = NEW_PRIVATE("Promise#value"); 54 var promiseValue = NEW_PRIVATE("Promise#value");
55 var promiseOnResolve = NEW_PRIVATE("Promise#onResolve"); 55 var promiseOnResolve = NEW_PRIVATE("Promise#onResolve");
56 var promiseOnReject = NEW_PRIVATE("Promise#onReject"); 56 var promiseOnReject = NEW_PRIVATE("Promise#onReject");
57 var promiseRaw = NEW_PRIVATE("Promise#raw"); 57 var promiseRaw = NEW_PRIVATE("Promise#raw");
58 58
59 function IsPromise(x) { 59 function IsPromise(x) {
60 return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus); 60 return IS_SPEC_OBJECT(x) && %HasLocalProperty(x, promiseStatus);
61 } 61 }
62 62
63 function Promise(resolver) { 63 function Promise(resolver) {
yhirano 2013/12/09 02:31:36 I'm still not sure. The spec has not been changed
rossberg 2013/12/10 10:11:15 No, but the spec requires that exceptions from the
yhirano 2013/12/11 04:46:31 Then can you write a comment?
rossberg 2014/01/09 12:51:43 Changed to throw
64 if (resolver === promiseRaw) return; 64 if (resolver === promiseRaw) return;
65 if (!%_IsConstructCall()) throw MakeTypeError('not_a_promise', [this]);
65 var promise = PromiseInit(this); 66 var promise = PromiseInit(this);
66 resolver(function(x) { PromiseResolve(promise, x) }, 67 try {
67 function(r) { PromiseReject(promise, r) }); 68 resolver(function(x) { PromiseResolve(promise, x) },
68 // TODO(rossberg): current draft makes exception from this call asynchronous, 69 function(r) { PromiseReject(promise, r) });
69 // but that's probably a mistake. 70 } catch (e) {
71 PromiseReject(promise, e);
72 }
70 } 73 }
71 74
72 function PromiseSet(promise, status, value, onResolve, onReject) { 75 function PromiseSet(promise, status, value, onResolve, onReject) {
73 SET_PRIVATE(promise, promiseStatus, status); 76 SET_PRIVATE(promise, promiseStatus, status);
74 SET_PRIVATE(promise, promiseValue, value); 77 SET_PRIVATE(promise, promiseValue, value);
75 SET_PRIVATE(promise, promiseOnResolve, onResolve); 78 SET_PRIVATE(promise, promiseOnResolve, onResolve);
76 SET_PRIVATE(promise, promiseOnReject, onReject); 79 SET_PRIVATE(promise, promiseOnReject, onReject);
77 return promise; 80 return promise;
78 } 81 }
79 82
80 function PromiseInit(promise) { 83 function PromiseInit(promise) {
81 return PromiseSet(promise, 0, UNDEFINED, new InternalArray, new InternalArray) 84 return PromiseSet(promise, 0, UNDEFINED, new InternalArray, new InternalArray)
82 } 85 }
83 86
84 function PromiseDone(promise, status, value, promiseQueue) { 87 function PromiseDone(promise, status, value, promiseQueue) {
85 if (GET_PRIVATE(promise, promiseStatus) !== 0) return; 88 if (GET_PRIVATE(promise, promiseStatus) === 0) {
86 PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue)); 89 PromiseEnqueue(value, GET_PRIVATE(promise, promiseQueue));
87 PromiseSet(promise, status, value); 90 PromiseSet(promise, status, value);
91 }
88 } 92 }
89 93
90 function PromiseResolve(promise, x) { 94 function PromiseResolve(promise, x) {
91 PromiseDone(promise, +1, x, promiseOnResolve) 95 PromiseDone(promise, +1, x, promiseOnResolve)
92 } 96 }
93 97
94 function PromiseReject(promise, r) { 98 function PromiseReject(promise, r) {
95 PromiseDone(promise, -1, r, promiseOnReject) 99 PromiseDone(promise, -1, r, promiseOnReject)
96 } 100 }
97 101
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) : 216 return x === that ? onReject(MakeTypeError('promise_cyclic', [x])) :
213 IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x); 217 IsPromise(x) ? x.then(onResolve, onReject) : onResolve(x);
214 }, 218 },
215 onReject 219 onReject
216 ); 220 );
217 } 221 }
218 222
219 PromiseCoerce.table = new $WeakMap; 223 PromiseCoerce.table = new $WeakMap;
220 224
221 function PromiseCoerce(constructor, x) { 225 function PromiseCoerce(constructor, x) {
222 var then; 226 if (!(IsPromise(x) || IS_NULL_OR_UNDEFINED(x))) {
223 if (IsPromise(x)) { 227 var then = x.then;
224 return x; 228 if (typeof then === 'function') {
225 } else if (!IS_NULL_OR_UNDEFINED(x) && %IsCallable(then = x.then)) { 229 if (PromiseCoerce.table.has(x)) {
226 if (PromiseCoerce.table.has(x)) { 230 return PromiseCoerce.table.get(x);
227 return PromiseCoerce.table.get(x); 231 } else {
228 } else { 232 var deferred = %_CallFunction(constructor, PromiseDeferred);
229 var deferred = constructor.deferred(); 233 PromiseCoerce.table.set(x, deferred.promise);
230 PromiseCoerce.table.set(x, deferred.promise); 234 try {
231 try { 235 %_CallFunction(x, deferred.resolve, deferred.reject, then);
232 %_CallFunction(x, deferred.resolve, deferred.reject, then); 236 } catch(e) {
233 } catch(e) { 237 deferred.reject(e);
234 deferred.reject(e); 238 }
239 return deferred.promise;
235 } 240 }
236 return deferred.promise;
237 } 241 }
238 } else {
239 return x;
240 } 242 }
243 return x;
241 } 244 }
242 245
243 246
244 // Combinators. 247 // Combinators.
245 248
246 function PromiseCast(x) { 249 function PromiseCast(x) {
247 // TODO(rossberg): cannot do better until we support @@create. 250 // TODO(rossberg): cannot do better until we support @@create.
248 return IsPromise(x) ? x : this.resolved(x); 251 return IsPromise(x) ? x : this.resolve(x);
249 } 252 }
250 253
251 function PromiseAll(values) { 254 function PromiseAll(values) {
252 var deferred = this.deferred(); 255 var deferred = %_CallFunction(this, PromiseDeferred);
253 var resolutions = []; 256 var resolutions = [];
254 var count = values.length; 257 try {
255 if (count === 0) { 258 var count = values.length;
256 deferred.resolve(resolutions); 259 if (count === 0) {
257 } else { 260 deferred.resolve(resolutions);
258 for (var i = 0; i < values.length; ++i) { 261 } else {
259 this.cast(values[i]).chain( 262 for (var i = 0; i < values.length; ++i) {
260 function(i, x) { 263 this.cast(values[i]).chain(
261 resolutions[i] = x; 264 function(i, x) {
262 if (--count === 0) deferred.resolve(resolutions); 265 resolutions[i] = x;
263 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available 266 if (--count === 0) deferred.resolve(resolutions);
264 function(r) { 267 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available
265 if (count > 0) { count = 0; deferred.reject(r) } 268 function(r) { deferred.reject(r) }
266 } 269 );
267 ); 270 }
268 } 271 }
272 } catch (e) {
273 deferred.reject(e)
269 } 274 }
270 return deferred.promise; 275 return deferred.promise;
271 } 276 }
272 277
273 function PromiseOne(values) { // a.k.a. race 278 function PromiseOne(values) { // a.k.a. race
274 var deferred = this.deferred(); 279 var deferred = %_CallFunction(this, PromiseDeferred);
275 var done = false; 280 try {
276 for (var i = 0; i < values.length; ++i) { 281 for (var i = 0; i < values.length; ++i) {
277 this.cast(values[i]).chain( 282 this.cast(values[i]).chain(
278 function(x) { if (!done) { done = true; deferred.resolve(x) } }, 283 function(x) { deferred.resolve(x) },
279 function(r) { if (!done) { done = true; deferred.reject(r) } } 284 function(r) { deferred.reject(r) }
280 ); 285 );
286 }
287 } catch (e) {
288 deferred.reject(e)
281 } 289 }
282 return deferred.promise; 290 return deferred.promise;
283 } 291 }
284 292
285 //------------------------------------------------------------------- 293 //-------------------------------------------------------------------
286 294
287 function SetUpPromise() { 295 function SetUpPromise() {
288 %CheckIsBootstrapping() 296 %CheckIsBootstrapping()
289 global.Promise = $Promise; 297 global.Promise = $Promise;
290 InstallFunctions($Promise, DONT_ENUM, [ 298 InstallFunctions($Promise, DONT_ENUM, [
291 "deferred", PromiseDeferred, 299 "defer", PromiseDeferred,
292 "resolved", PromiseResolved, 300 "resolve", PromiseResolved,
293 "rejected", PromiseRejected, 301 "reject", PromiseRejected,
294 "all", PromiseAll, 302 "all", PromiseAll,
295 "one", PromiseOne, 303 "one", PromiseOne,
arv (Not doing code reviews) 2013/12/10 14:21:24 This should be race
rossberg 2014/01/09 12:51:43 Done.
296 "cast", PromiseCast 304 "cast", PromiseCast
297 ]); 305 ]);
298 InstallFunctions($Promise.prototype, DONT_ENUM, [ 306 InstallFunctions($Promise.prototype, DONT_ENUM, [
299 "chain", PromiseChain, 307 "chain", PromiseChain,
300 "then", PromiseThen, 308 "then", PromiseThen,
301 "catch", PromiseCatch 309 "catch", PromiseCatch
302 ]); 310 ]);
303 } 311 }
304 312
305 SetUpPromise(); 313 SetUpPromise();
OLDNEW
« no previous file with comments | « src/messages.js ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698