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

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: 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
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 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
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) {
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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 var then;
223 if (IsPromise(x)) { 227 if (IsPromise(x)) {
224 return x; 228 return x;
225 } else if (!IS_NULL_OR_UNDEFINED(x) && %IsCallable(then = x.then)) { 229 } else if (!IS_NULL_OR_UNDEFINED(x) &&
230 typeof (then = x.then) === 'function') {
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Can we not have assignments in conditions? Pretty
rossberg 2013/12/06 11:43:29 Done.
226 if (PromiseCoerce.table.has(x)) { 231 if (PromiseCoerce.table.has(x)) {
227 return PromiseCoerce.table.get(x); 232 return PromiseCoerce.table.get(x);
228 } else { 233 } else {
229 var deferred = constructor.deferred(); 234 var deferred = %_CallFunction(constructor, PromiseDeferred);
230 PromiseCoerce.table.set(x, deferred.promise); 235 PromiseCoerce.table.set(x, deferred.promise);
231 try { 236 try {
232 %_CallFunction(x, deferred.resolve, deferred.reject, then); 237 %_CallFunction(x, deferred.resolve, deferred.reject, then);
233 } catch(e) { 238 } catch(e) {
234 deferred.reject(e); 239 deferred.reject(e);
235 } 240 }
236 return deferred.promise; 241 return deferred.promise;
237 } 242 }
238 } else { 243 } else {
239 return x; 244 return x;
240 } 245 }
241 } 246 }
242 247
243 248
244 // Combinators. 249 // Combinators.
245 250
246 function PromiseCast(x) { 251 function PromiseCast(x) {
247 // TODO(rossberg): cannot do better until we support @@create. 252 // TODO(rossberg): cannot do better until we support @@create.
248 return IsPromise(x) ? x : this.resolved(x); 253 return IsPromise(x) ? x : this.resolve(x);
249 } 254 }
250 255
251 function PromiseAll(values) { 256 function PromiseAll(values) {
252 var deferred = this.deferred(); 257 var deferred = %_CallFunction(this, PromiseDeferred);
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Instead of using %_CallFunction here and above, le
rossberg 2013/12/06 11:43:29 Why? Avoiding extra hoops like that is exactly why
253 var resolutions = []; 258 var resolutions = [];
254 var count = values.length; 259 try {
255 if (count === 0) { 260 var count = values.length;
256 deferred.resolve(resolutions); 261 if (count === 0) {
257 } else { 262 deferred.resolve(resolutions);
258 for (var i = 0; i < values.length; ++i) { 263 } else {
259 this.cast(values[i]).chain( 264 for (var i = 0; i < values.length; ++i) {
260 function(i, x) { 265 this.cast(values[i]).chain(
261 resolutions[i] = x; 266 function(i, x) {
262 if (--count === 0) deferred.resolve(resolutions); 267 resolutions[i] = x;
263 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available 268 if (--count === 0) deferred.resolve(resolutions);
264 function(r) { 269 }.bind(UNDEFINED, i), // TODO(rossberg): use let loop once available
265 if (count > 0) { count = 0; deferred.reject(r) } 270 function(r) { deferred.reject(r) }
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Why 'count > 0' condition disappeared here? What i
rossberg 2013/12/06 11:43:29 Reject used to throw on non-pending promises in an
266 } 271 );
267 ); 272 }
268 } 273 }
274 } catch (e) {
275 deferred.reject(e)
269 } 276 }
270 return deferred.promise; 277 return deferred.promise;
271 } 278 }
272 279
273 function PromiseOne(values) { // a.k.a. race 280 function PromiseOne(values) { // a.k.a. race
274 var deferred = this.deferred(); 281 var deferred = %_CallFunction(this, PromiseDeferred);
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 Ditto re: %_CallFunction
275 var done = false; 282 try {
276 for (var i = 0; i < values.length; ++i) { 283 for (var i = 0; i < values.length; ++i) {
277 this.cast(values[i]).chain( 284 this.cast(values[i]).chain(
278 function(x) { if (!done) { done = true; deferred.resolve(x) } }, 285 function(x) { deferred.resolve(x) },
279 function(r) { if (!done) { done = true; deferred.reject(r) } } 286 function(r) { deferred.reject(r) }
280 ); 287 );
288 }
289 } catch (e) {
290 deferred.reject(e)
281 } 291 }
282 return deferred.promise; 292 return deferred.promise;
283 } 293 }
284 294
285 //------------------------------------------------------------------- 295 //-------------------------------------------------------------------
286 296
287 function SetUpPromise() { 297 function SetUpPromise() {
288 %CheckIsBootstrapping() 298 %CheckIsBootstrapping()
289 global.Promise = $Promise; 299 global.Promise = $Promise;
290 InstallFunctions($Promise, DONT_ENUM, [ 300 InstallFunctions($Promise, DONT_ENUM, [
291 "deferred", PromiseDeferred, 301 "defer", PromiseDeferred,
Dmitry Lomov (no reviews) 2013/12/04 09:24:43 So, my understanding is that 'defer' is non-standa
rossberg 2013/12/06 11:43:29 As per off-line discussion, I leave it in for the
292 "resolved", PromiseResolved, 302 "resolve", PromiseResolved,
293 "rejected", PromiseRejected, 303 "reject", PromiseRejected,
294 "all", PromiseAll, 304 "all", PromiseAll,
295 "one", PromiseOne, 305 "one", PromiseOne,
296 "cast", PromiseCast 306 "cast", PromiseCast
297 ]); 307 ]);
298 InstallFunctions($Promise.prototype, DONT_ENUM, [ 308 InstallFunctions($Promise.prototype, DONT_ENUM, [
299 "chain", PromiseChain, 309 "chain", PromiseChain,
300 "then", PromiseThen, 310 "then", PromiseThen,
301 "catch", PromiseCatch 311 "catch", PromiseCatch
302 ]); 312 ]);
303 } 313 }
304 314
305 SetUpPromise(); 315 SetUpPromise();
OLDNEW
« no previous file with comments | « src/messages.js ('k') | src/runtime.h » ('j') | test/mjsunit/harmony/promises.js » ('J')

Powered by Google App Engine
This is Rietveld 408576698