2 * Copyright (C) 2013 Apple Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
27 #include "JSPromiseConstructor.h"
32 #include "JSCJSValueInlines.h"
33 #include "JSCellInlines.h"
34 #include "JSPromise.h"
35 #include "JSPromiseDeferred.h"
36 #include "JSPromiseFunctions.h"
37 #include "JSPromisePrototype.h"
39 #include "NumberObject.h"
40 #include "StructureInlines.h"
44 STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(JSPromiseConstructor
);
46 static EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncCast(ExecState
*);
47 static EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncResolve(ExecState
*);
48 static EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncReject(ExecState
*);
49 static EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncRace(ExecState
*);
50 static EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncAll(ExecState
*);
53 #include "JSPromiseConstructor.lut.h"
57 const ClassInfo
JSPromiseConstructor::s_info
= { "Function", &InternalFunction::s_info
, 0, ExecState::promiseConstructorTable
, CREATE_METHOD_TABLE(JSPromiseConstructor
) };
59 /* Source for JSPromiseConstructor.lut.h
60 @begin promiseConstructorTable
61 cast JSPromiseConstructorFuncCast DontEnum|Function 1
62 resolve JSPromiseConstructorFuncResolve DontEnum|Function 1
63 reject JSPromiseConstructorFuncReject DontEnum|Function 1
64 race JSPromiseConstructorFuncRace DontEnum|Function 1
65 all JSPromiseConstructorFuncAll DontEnum|Function 1
69 JSPromiseConstructor
* JSPromiseConstructor::create(VM
& vm
, Structure
* structure
, JSPromisePrototype
* promisePrototype
)
71 JSPromiseConstructor
* constructor
= new (NotNull
, allocateCell
<JSPromiseConstructor
>(vm
.heap
)) JSPromiseConstructor(vm
, structure
);
72 constructor
->finishCreation(vm
, promisePrototype
);
76 Structure
* JSPromiseConstructor::createStructure(VM
& vm
, JSGlobalObject
* globalObject
, JSValue prototype
)
78 return Structure::create(vm
, globalObject
, prototype
, TypeInfo(ObjectType
, StructureFlags
), info());
81 JSPromiseConstructor::JSPromiseConstructor(VM
& vm
, Structure
* structure
)
82 : InternalFunction(vm
, structure
)
86 void JSPromiseConstructor::finishCreation(VM
& vm
, JSPromisePrototype
* promisePrototype
)
88 Base::finishCreation(vm
, "Promise");
89 putDirectWithoutTransition(vm
, vm
.propertyNames
->prototype
, promisePrototype
, DontEnum
| DontDelete
| ReadOnly
);
90 putDirectWithoutTransition(vm
, vm
.propertyNames
->length
, jsNumber(1), ReadOnly
| DontEnum
| DontDelete
);
93 static EncodedJSValue JSC_HOST_CALL
constructPromise(ExecState
* exec
)
95 // NOTE: We ignore steps 1-4 as they only matter if you support subclassing, which we do not yet.
96 // 1. Let promise be the this value.
97 // 2. If Type(promise) is not Object, then throw a TypeError exception.
98 // 3. If promise does not have a [[PromiseStatus]] internal slot, then throw a TypeError exception.
99 // 4. If promise's [[PromiseStatus]] internal slot is not undefined, then throw a TypeError exception.
101 JSValue resolver
= exec
->argument(0);
103 // 5. IsCallable(resolver) is false, then throw a TypeError exception
105 CallType callType
= getCallData(resolver
, callData
);
106 if (callType
== CallTypeNone
)
107 return JSValue::encode(throwTypeError(exec
, ASCIILiteral("Promise constructor takes a function argument")));
110 JSGlobalObject
* globalObject
= exec
->callee()->globalObject();
112 JSPromise
* promise
= JSPromise::create(vm
, globalObject
, jsCast
<JSPromiseConstructor
*>(exec
->callee()));
114 // NOTE: Steps 6-8 are handled by JSPromise::create().
115 // 6. Set promise's [[PromiseStatus]] internal slot to "unresolved".
116 // 7. Set promise's [[ResolveReactions]] internal slot to a new empty List.
117 // 8. Set promise's [[RejectReactions]] internal slot to a new empty List.
119 // 9. Let 'resolve' be a new built-in function object as defined in Resolve Promise Functions.
120 JSFunction
* resolve
= createResolvePromiseFunction(vm
, globalObject
);
122 // 10. Set the [[Promise]] internal slot of 'resolve' to 'promise'.
123 resolve
->putDirect(vm
, vm
.propertyNames
->promisePrivateName
, promise
);
125 // 11. Let 'reject' be a new built-in function object as defined in Reject Promise Functions
126 JSFunction
* reject
= createRejectPromiseFunction(vm
, globalObject
);
128 // 12. Set the [[Promise]] internal slot of 'reject' to 'promise'.
129 reject
->putDirect(vm
, vm
.propertyNames
->promisePrivateName
, promise
);
131 // 13. Let 'result' be the result of calling the [[Call]] internal method of resolver with
132 // undefined as thisArgument and a List containing resolve and reject as argumentsList.
133 MarkedArgumentBuffer arguments
;
134 arguments
.append(resolve
);
135 arguments
.append(reject
);
136 call(exec
, resolver
, callType
, callData
, jsUndefined(), arguments
);
138 // 14. If result is an abrupt completion, call PromiseReject(promise, result.[[value]]).
139 if (exec
->hadException()) {
140 JSValue exception
= exec
->exception();
141 exec
->clearException();
143 promise
->reject(vm
, exception
);
146 // 15. Return promise.
147 return JSValue::encode(promise
);
150 ConstructType
JSPromiseConstructor::getConstructData(JSCell
*, ConstructData
& constructData
)
152 constructData
.native
.function
= constructPromise
;
153 return ConstructTypeHost
;
156 CallType
JSPromiseConstructor::getCallData(JSCell
*, CallData
& callData
)
158 callData
.native
.function
= constructPromise
;
162 bool JSPromiseConstructor::getOwnPropertySlot(JSObject
* object
, ExecState
* exec
, PropertyName propertyName
, PropertySlot
& slot
)
164 return getStaticFunctionSlot
<InternalFunction
>(exec
, ExecState::promiseConstructorTable(exec
->vm()), jsCast
<JSPromiseConstructor
*>(object
), propertyName
, slot
);
167 EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncCast(ExecState
* exec
)
169 // -- Promise.cast(x) --
170 JSValue x
= exec
->argument(0);
172 // 1. Let 'C' be the this value.
173 JSValue C
= exec
->thisValue();
175 // 2. If IsPromise(x) is true,
176 JSPromise
* promise
= jsDynamicCast
<JSPromise
*>(x
);
178 // i. Let 'constructor' be the value of x's [[PromiseConstructor]] internal slot.
179 JSValue constructor
= promise
->constructor();
180 // ii. If SameValue(constructor, C) is true, return x.
181 if (sameValue(exec
, constructor
, C
))
182 return JSValue::encode(x
);
185 // 3. Let 'deferred' be the result of calling GetDeferred(C).
186 JSValue deferredValue
= createJSPromiseDeferredFromConstructor(exec
, C
);
188 // 4. ReturnIfAbrupt(deferred).
189 if (exec
->hadException())
190 return JSValue::encode(jsUndefined());
192 JSPromiseDeferred
* deferred
= jsCast
<JSPromiseDeferred
*>(deferredValue
);
194 // 5. Let 'resolveResult' be the result of calling the [[Call]] internal method
195 // of deferred.[[Resolve]] with undefined as thisArgument and a List containing x
197 performDeferredResolve(exec
, deferred
, x
);
199 // 6. ReturnIfAbrupt(resolveResult).
200 if (exec
->hadException())
201 return JSValue::encode(jsUndefined());
203 // 7. Return deferred.[[Promise]].
204 return JSValue::encode(deferred
->promise());
207 EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncResolve(ExecState
* exec
)
209 // -- Promise.resolve(x) --
210 JSValue x
= exec
->argument(0);
212 // 1. Let 'C' be the this value.
213 JSValue C
= exec
->thisValue();
215 // 2. Let 'deferred' be the result of calling GetDeferred(C).
216 JSValue deferredValue
= createJSPromiseDeferredFromConstructor(exec
, C
);
218 // 3. ReturnIfAbrupt(deferred).
219 if (exec
->hadException())
220 return JSValue::encode(jsUndefined());
222 JSPromiseDeferred
* deferred
= jsCast
<JSPromiseDeferred
*>(deferredValue
);
224 // 4. Let 'resolveResult' be the result of calling the [[Call]] internal method
225 // of deferred.[[Resolve]] with undefined as thisArgument and a List containing x
227 performDeferredResolve(exec
, deferred
, x
);
229 // 5. ReturnIfAbrupt(resolveResult).
230 if (exec
->hadException())
231 return JSValue::encode(jsUndefined());
233 // 6. Return deferred.[[Promise]].
234 return JSValue::encode(deferred
->promise());
237 EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncReject(ExecState
* exec
)
239 // -- Promise.reject(x) --
240 JSValue r
= exec
->argument(0);
242 // 1. Let 'C' be the this value.
243 JSValue C
= exec
->thisValue();
245 // 2. Let 'deferred' be the result of calling GetDeferred(C).
246 JSValue deferredValue
= createJSPromiseDeferredFromConstructor(exec
, C
);
248 // 3. ReturnIfAbrupt(deferred).
249 if (exec
->hadException())
250 return JSValue::encode(jsUndefined());
252 JSPromiseDeferred
* deferred
= jsCast
<JSPromiseDeferred
*>(deferredValue
);
254 // 4. Let 'rejectResult' be the result of calling the [[Call]] internal method
255 // of deferred.[[Reject]] with undefined as thisArgument and a List containing r
257 performDeferredReject(exec
, deferred
, r
);
259 // 5. ReturnIfAbrupt(resolveResult).
260 if (exec
->hadException())
261 return JSValue::encode(jsUndefined());
263 // 6. Return deferred.[[Promise]].
264 return JSValue::encode(deferred
->promise());
267 EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncRace(ExecState
* exec
)
269 // -- Promise.race(iterable) --
270 JSValue iterable
= exec
->argument(0);
273 // 1. Let 'C' be the this value.
274 JSValue C
= exec
->thisValue();
276 // 2. Let 'deferred' be the result of calling GetDeferred(C).
277 JSValue deferredValue
= createJSPromiseDeferredFromConstructor(exec
, C
);
279 // 3. ReturnIfAbrupt(deferred).
280 if (exec
->hadException())
281 return JSValue::encode(jsUndefined());
283 JSPromiseDeferred
* deferred
= jsCast
<JSPromiseDeferred
*>(deferredValue
);
285 // 4. Let 'iterator' be the result of calling GetIterator(iterable).
286 JSValue iteratorFunction
= iterable
.get(exec
, vm
.propertyNames
->iteratorPrivateName
);
287 if (exec
->hadException())
288 return JSValue::encode(abruptRejection(exec
, deferred
));
290 CallData iteratorFunctionCallData
;
291 CallType iteratorFunctionCallType
= getCallData(iteratorFunction
, iteratorFunctionCallData
);
292 if (iteratorFunctionCallType
== CallTypeNone
) {
293 throwTypeError(exec
);
294 return JSValue::encode(abruptRejection(exec
, deferred
));
297 ArgList iteratorFunctionArguments
;
298 JSValue iterator
= call(exec
, iteratorFunction
, iteratorFunctionCallType
, iteratorFunctionCallData
, iterable
, iteratorFunctionArguments
);
300 // 5. RejectIfAbrupt(iterator, deferred).
301 if (exec
->hadException())
302 return JSValue::encode(abruptRejection(exec
, deferred
));
306 // i. Let 'next' be the result of calling IteratorStep(iterator).
307 JSValue nextFunction
= iterator
.get(exec
, exec
->vm().propertyNames
->iteratorNextPrivateName
);
308 if (exec
->hadException())
309 return JSValue::encode(abruptRejection(exec
, deferred
));
311 CallData nextFunctionCallData
;
312 CallType nextFunctionCallType
= getCallData(nextFunction
, nextFunctionCallData
);
313 if (nextFunctionCallType
== CallTypeNone
) {
314 throwTypeError(exec
);
315 return JSValue::encode(abruptRejection(exec
, deferred
));
318 MarkedArgumentBuffer nextFunctionArguments
;
319 nextFunctionArguments
.append(jsUndefined());
320 JSValue next
= call(exec
, nextFunction
, nextFunctionCallType
, nextFunctionCallData
, iterator
, nextFunctionArguments
);
322 // ii. RejectIfAbrupt(next, deferred).
323 if (exec
->hadException())
324 return JSValue::encode(abruptRejection(exec
, deferred
));
326 // iii. If 'next' is false, return deferred.[[Promise]].
327 // Note: We implement this as an iterationTerminator
328 if (next
== vm
.iterationTerminator
.get())
329 return JSValue::encode(deferred
->promise());
331 // iv. Let 'nextValue' be the result of calling IteratorValue(next).
332 // v. RejectIfAbrupt(nextValue, deferred).
333 // Note: 'next' is already the value, so there is nothing to do here.
335 // vi. Let 'nextPromise' be the result of calling Invoke(C, "cast", (nextValue)).
336 JSValue castFunction
= C
.get(exec
, vm
.propertyNames
->cast
);
337 if (exec
->hadException())
338 return JSValue::encode(abruptRejection(exec
, deferred
));
340 CallData castFunctionCallData
;
341 CallType castFunctionCallType
= getCallData(castFunction
, castFunctionCallData
);
342 if (castFunctionCallType
== CallTypeNone
) {
343 throwTypeError(exec
);
344 return JSValue::encode(abruptRejection(exec
, deferred
));
347 MarkedArgumentBuffer castFunctionArguments
;
348 castFunctionArguments
.append(next
);
349 JSValue nextPromise
= call(exec
, castFunction
, castFunctionCallType
, castFunctionCallData
, C
, castFunctionArguments
);
351 // vii. RejectIfAbrupt(nextPromise, deferred).
352 if (exec
->hadException())
353 return JSValue::encode(abruptRejection(exec
, deferred
));
355 // viii. Let 'result' be the result of calling Invoke(nextPromise, "then", (deferred.[[Resolve]], deferred.[[Reject]])).
356 JSValue thenFunction
= nextPromise
.get(exec
, vm
.propertyNames
->then
);
357 if (exec
->hadException())
358 return JSValue::encode(abruptRejection(exec
, deferred
));
360 CallData thenFunctionCallData
;
361 CallType thenFunctionCallType
= getCallData(thenFunction
, thenFunctionCallData
);
362 if (thenFunctionCallType
== CallTypeNone
) {
363 throwTypeError(exec
);
364 return JSValue::encode(abruptRejection(exec
, deferred
));
367 MarkedArgumentBuffer thenFunctionArguments
;
368 thenFunctionArguments
.append(deferred
->resolve());
369 thenFunctionArguments
.append(deferred
->reject());
371 call(exec
, thenFunction
, thenFunctionCallType
, thenFunctionCallData
, nextPromise
, thenFunctionArguments
);
373 // ix. RejectIfAbrupt(result, deferred).
374 if (exec
->hadException())
375 return JSValue::encode(abruptRejection(exec
, deferred
));
379 EncodedJSValue JSC_HOST_CALL
JSPromiseConstructorFuncAll(ExecState
* exec
)
381 // -- Promise.all(iterable) --
383 JSValue iterable
= exec
->argument(0);
386 // 1. Let 'C' be the this value.
387 JSValue C
= exec
->thisValue();
389 // 2. Let 'deferred' be the result of calling GetDeferred(C).
390 JSValue deferredValue
= createJSPromiseDeferredFromConstructor(exec
, C
);
392 // 3. ReturnIfAbrupt(deferred).
393 if (exec
->hadException())
394 return JSValue::encode(jsUndefined());
396 // NOTE: A non-abrupt completion of createJSPromiseDeferredFromConstructor implies that
397 // C and deferredValue are objects.
398 JSObject
* thisObject
= asObject(C
);
399 JSPromiseDeferred
* deferred
= jsCast
<JSPromiseDeferred
*>(deferredValue
);
401 // 4. Let 'iterator' be the result of calling GetIterator(iterable).
402 JSValue iteratorFunction
= iterable
.get(exec
, vm
.propertyNames
->iteratorPrivateName
);
403 if (exec
->hadException())
404 return JSValue::encode(abruptRejection(exec
, deferred
));
406 CallData iteratorFunctionCallData
;
407 CallType iteratorFunctionCallType
= getCallData(iteratorFunction
, iteratorFunctionCallData
);
408 if (iteratorFunctionCallType
== CallTypeNone
) {
409 throwTypeError(exec
);
410 return JSValue::encode(abruptRejection(exec
, deferred
));
413 ArgList iteratorFunctionArguments
;
414 JSValue iterator
= call(exec
, iteratorFunction
, iteratorFunctionCallType
, iteratorFunctionCallData
, iterable
, iteratorFunctionArguments
);
416 // 5. RejectIfAbrupt(iterator, deferred).
417 if (exec
->hadException())
418 return JSValue::encode(abruptRejection(exec
, deferred
));
420 // 6. Let 'values' be the result of calling ArrayCreate(0).
421 JSArray
* values
= constructEmptyArray(exec
, nullptr, thisObject
->globalObject());
423 // 7. Let 'countdownHolder' be Record { [[Countdown]]: 0 }.
424 NumberObject
* countdownHolder
= constructNumber(exec
, thisObject
->globalObject(), JSValue(0));
426 // 8. Let 'index' be 0.
431 // i. Let 'next' be the result of calling IteratorStep(iterator).
432 JSValue nextFunction
= iterator
.get(exec
, exec
->vm().propertyNames
->iteratorNextPrivateName
);
433 if (exec
->hadException())
434 return JSValue::encode(abruptRejection(exec
, deferred
));
436 CallData nextFunctionCallData
;
437 CallType nextFunctionCallType
= getCallData(nextFunction
, nextFunctionCallData
);
438 if (nextFunctionCallType
== CallTypeNone
) {
439 throwTypeError(exec
);
440 return JSValue::encode(abruptRejection(exec
, deferred
));
443 MarkedArgumentBuffer nextFunctionArguments
;
444 nextFunctionArguments
.append(jsUndefined());
445 JSValue next
= call(exec
, nextFunction
, nextFunctionCallType
, nextFunctionCallData
, iterator
, nextFunctionArguments
);
447 // ii. RejectIfAbrupt(next, deferred).
448 if (exec
->hadException())
449 return JSValue::encode(abruptRejection(exec
, deferred
));
451 // iii. If 'next' is false,
452 // Note: We implement this as an iterationTerminator
453 if (next
== vm
.iterationTerminator
.get()) {
454 // a. If 'index' is 0,
456 // a. Let 'resolveResult' be the result of calling the [[Call]] internal method
457 // of deferred.[[Resolve]] with undefined as thisArgument and a List containing
458 // values as argumentsList.
459 performDeferredResolve(exec
, deferred
, values
);
461 // b. ReturnIfAbrupt(resolveResult).
462 if (exec
->hadException())
463 return JSValue::encode(jsUndefined());
466 // b. Return deferred.[[Promise]].
467 return JSValue::encode(deferred
->promise());
470 // iv. Let 'nextValue' be the result of calling IteratorValue(next).
471 // v. RejectIfAbrupt(nextValue, deferred).
472 // Note: 'next' is already the value, so there is nothing to do here.
474 // vi. Let 'nextPromise' be the result of calling Invoke(C, "cast", (nextValue)).
475 JSValue castFunction
= C
.get(exec
, vm
.propertyNames
->cast
);
476 if (exec
->hadException())
477 return JSValue::encode(abruptRejection(exec
, deferred
));
479 CallData castFunctionCallData
;
480 CallType castFunctionCallType
= getCallData(castFunction
, castFunctionCallData
);
481 if (castFunctionCallType
== CallTypeNone
) {
482 throwTypeError(exec
);
483 return JSValue::encode(abruptRejection(exec
, deferred
));
486 MarkedArgumentBuffer castFunctionArguments
;
487 castFunctionArguments
.append(next
);
488 JSValue nextPromise
= call(exec
, castFunction
, castFunctionCallType
, castFunctionCallData
, C
, castFunctionArguments
);
490 // vii. RejectIfAbrupt(nextPromise, deferred).
491 if (exec
->hadException())
492 return JSValue::encode(abruptRejection(exec
, deferred
));
494 // viii. Let 'countdownFunction' be a new built-in function object as defined in Promise.all Countdown Functions.
495 JSFunction
* countdownFunction
= createPromiseAllCountdownFunction(vm
, thisObject
->globalObject());
497 // ix. Set the [[Index]] internal slot of 'countdownFunction' to 'index'.
498 countdownFunction
->putDirect(vm
, vm
.propertyNames
->indexPrivateName
, JSValue(index
));
500 // x. Set the [[Values]] internal slot of 'countdownFunction' to 'values'.
501 countdownFunction
->putDirect(vm
, vm
.propertyNames
->valuesPrivateName
, values
);
503 // xi. Set the [[Deferred]] internal slot of 'countdownFunction' to 'deferred'.
504 countdownFunction
->putDirect(vm
, vm
.propertyNames
->deferredPrivateName
, deferred
);
506 // xii. Set the [[CountdownHolder]] internal slot of 'countdownFunction' to 'countdownHolder'.
507 countdownFunction
->putDirect(vm
, vm
.propertyNames
->countdownHolderPrivateName
, countdownHolder
);
509 // xiii. Let 'result' be the result of calling Invoke(nextPromise, "then", (countdownFunction, deferred.[[Reject]])).
510 JSValue thenFunction
= nextPromise
.get(exec
, vm
.propertyNames
->then
);
511 if (exec
->hadException())
512 return JSValue::encode(abruptRejection(exec
, deferred
));
514 CallData thenFunctionCallData
;
515 CallType thenFunctionCallType
= getCallData(thenFunction
, thenFunctionCallData
);
516 if (thenFunctionCallType
== CallTypeNone
) {
517 throwTypeError(exec
);
518 return JSValue::encode(abruptRejection(exec
, deferred
));
521 MarkedArgumentBuffer thenFunctionArguments
;
522 thenFunctionArguments
.append(countdownFunction
);
523 thenFunctionArguments
.append(deferred
->reject());
525 call(exec
, thenFunction
, thenFunctionCallType
, thenFunctionCallData
, nextPromise
, thenFunctionArguments
);
527 // xiv. RejectIfAbrupt(result, deferred).
528 if (exec
->hadException())
529 return JSValue::encode(abruptRejection(exec
, deferred
));
531 // xv. Set index to index + 1.
534 // xvi. Set countdownHolder.[[Countdown]] to countdownHolder.[[Countdown]] + 1.
535 uint32_t newCountdownValue
= countdownHolder
->internalValue().asUInt32() + 1;
536 countdownHolder
->setInternalValue(vm
, JSValue(newCountdownValue
));
540 JSPromise
* constructPromise(ExecState
* exec
, JSGlobalObject
* globalObject
, JSFunction
* resolver
)
542 JSPromiseConstructor
* promiseConstructor
= globalObject
->promiseConstructor();
544 ConstructData constructData
;
545 ConstructType constructType
= getConstructData(promiseConstructor
, constructData
);
546 ASSERT(constructType
!= ConstructTypeNone
);
548 MarkedArgumentBuffer arguments
;
549 arguments
.append(resolver
);
551 return jsCast
<JSPromise
*>(construct(exec
, promiseConstructor
, constructType
, constructData
, arguments
));
556 #endif // ENABLE(PROMISES)