Implement other routines of Promise (#1729)

Add Promise.resolve, Promise.reject, Promise.race, Promise.all and
Promise.prototype.catch

Also it fixes the issue 1763

JerryScript-DCO-1.0-Signed-off-by: Zidong Jiang zidong.jiang@intel.com
This commit is contained in:
Zidong Jiang 2017-04-26 19:47:51 +08:00 committed by GitHub
parent 9d4123c3c4
commit 078f6e101d
20 changed files with 1044 additions and 138 deletions

View File

@ -13,9 +13,7 @@
* limitations under the License.
*/
#include "ecma-exceptions.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-promise-object.h"
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
@ -42,34 +40,36 @@
*
* See also: 25.4.5.3
*
* @return ecma value of a new promise object
* Returned value must be freed with ecma_free_value
* @return ecma value of a new promise object.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_prototype_then (ecma_value_t this_arg, /**< this argument */
ecma_value_t on_fulfilled, /**< on_fulfilled function */
ecma_value_t on_rejected) /**< on_rejected function */
{
ecma_object_t *obj = ecma_get_object_from_value (this_arg);
if (!ecma_is_promise (obj))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a Promise."));
}
ecma_value_t result_capability = ecma_promise_new_capability ();
if (ECMA_IS_VALUE_ERROR (result_capability))
{
return result_capability;
}
ecma_value_t ret = ecma_promise_then (this_arg, on_fulfilled, on_rejected, result_capability);
ecma_free_value (result_capability);
return ret;
return ecma_promise_then (this_arg,
on_fulfilled,
on_rejected);
} /* ecma_builtin_promise_prototype_then */
/**
* Promise routine: catch.
*
* See also: 25.4.5.1
*
* @return ecma value of a new promise object.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_prototype_catch (ecma_value_t this_arg, /**< this argument */
ecma_value_t on_rejected) /**< on_rejected function */
{
return ecma_promise_then (this_arg,
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
on_rejected);
} /* ecma_builtin_promise_prototype_catch */
/**
* @}
* @}

View File

@ -29,6 +29,7 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
ECMA_PROPERTY_FLAG_WRITABLE)
ROUTINE (LIT_MAGIC_STRING_THEN, ecma_builtin_promise_prototype_then, 2, 2)
ROUTINE (LIT_MAGIC_STRING_CATCH, ecma_builtin_promise_prototype_catch, 1, 1)
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */

View File

@ -13,9 +13,12 @@
* limitations under the License.
*/
#include "ecma-array-object.h"
#include "ecma-exceptions.h"
#include "ecma-function-object.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-number-object.h"
#include "ecma-promise-object.h"
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
@ -37,6 +40,615 @@
* @{
*/
/**
* The common function for 'reject' and 'resolve'.
*
* @return ecma value
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_reject_or_resolve (ecma_value_t this_arg, /**< "this" argument */
ecma_value_t argument, /**< argument for reject or resolve */
bool is_resolve) /**< whether it is for resolve routine */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not an object."));
}
uint8_t builtin_id = ecma_get_object_builtin_id (ecma_get_object_from_value (this_arg));
if (builtin_id != ECMA_BUILTIN_ID_PROMISE)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not the Promise constructor."));
}
if (is_resolve
&& ecma_is_value_object (argument)
&& ecma_is_promise (ecma_get_object_from_value (argument)))
{
return ecma_copy_value (argument);
}
ecma_value_t capability = ecma_promise_new_capability ();
if (ECMA_IS_VALUE_ERROR (capability))
{
return capability;
}
ecma_string_t *str;
if (is_resolve)
{
str = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
}
else
{
str = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
}
ecma_value_t func = ecma_op_object_get (ecma_get_object_from_value (capability), str);
ecma_deref_ecma_string (str);
ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (func),
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
&argument,
1);
ecma_free_value (func);
if (ECMA_IS_VALUE_ERROR (call_ret))
{
return call_ret;
}
ecma_free_value (call_ret);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
ecma_value_t promise_new = ecma_op_object_get (ecma_get_object_from_value (capability), str_promise);
ecma_deref_ecma_string (str_promise);
ecma_free_value (capability);
return promise_new;
} /* ecma_builtin_promise_reject_or_resolve */
/**
* Reject the promise if the value is error.
*
* See also:
* ES2015 25.4.1.1.1
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
inline static ecma_value_t
ecma_builtin_promise_reject_abrupt (ecma_value_t abrupt_value,
ecma_value_t capability)
{
ecma_value_t reason = ecma_get_value_from_error_value (abrupt_value);
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject);
ecma_deref_ecma_string (str_reject);
ecma_value_t call_ret = ecma_op_function_call (ecma_get_object_from_value (reject),
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
&reason,
1);
ecma_free_value (reject);
if (ECMA_IS_VALUE_ERROR (call_ret))
{
return call_ret;
}
ecma_free_value (call_ret);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
ecma_value_t promise_new = ecma_op_object_get (ecma_get_object_from_value (capability), str_promise);
ecma_deref_ecma_string (str_promise);
return promise_new;
} /* ecma_builtin_promise_reject_abrupt */
/**
* The Promise.reject routine.
*
* See also:
* ES2015 25.4.4.4
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_reject (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t reason) /**< the reason for reject */
{
return ecma_builtin_promise_reject_or_resolve (this_arg, reason, false);
} /* ecma_builtin_promise_reject */
/**
* The Promise.resolve routine.
*
* See also:
* ES2015 25.4.4.5
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_resolve (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t argument) /**< the argument for resolve */
{
return ecma_builtin_promise_reject_or_resolve (this_arg, argument, true);
} /* ecma_builtin_promise_resolve */
/**
* Runtime Semantics: PerformPromiseRace.
*
* See also:
* ES2015 25.4.4.3.1
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
inline static ecma_value_t
ecma_builtin_promise_do_race (ecma_value_t array, /**< the array for race */
ecma_value_t capability, /**< PromiseCapability record */
ecma_value_t ctor) /**< the caller of Promise.race */
{
JERRY_ASSERT (ecma_is_value_object (capability)
&& ecma_is_value_object (array)
&& ecma_is_value_object (ctor));
JERRY_ASSERT (ecma_get_object_builtin_id (ecma_get_object_from_value (ctor)) == ECMA_BUILTIN_ID_PROMISE);
JERRY_ASSERT (ecma_get_object_type (ecma_get_object_from_value (array)) == ECMA_OBJECT_TYPE_ARRAY);
ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
ecma_object_t *array_p = ecma_get_object_from_value (array);
ecma_value_t len_value = ecma_op_object_get (array_p, magic_string_length_p);
ecma_deref_ecma_string (magic_string_length_p);
ecma_length_t len = (ecma_length_t) ecma_get_integer_from_value (len_value);
ecma_fast_free_value (len_value);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability),
str_resolve);
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability),
str_reject);
for (ecma_length_t index = 0; index <= len; index++)
{
/* b-d. */
if (index == len)
{
ret = ecma_op_object_get (ecma_get_object_from_value (capability), str_promise);
break;
}
/* e. */
ecma_string_t *str_index = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t array_item = ecma_op_object_get (array_p, str_index);
ecma_deref_ecma_string (str_index);
/* h. */
ecma_value_t next_promise = ecma_builtin_promise_resolve (ctor, array_item);
ecma_free_value (array_item);
/* i. */
if (ECMA_IS_VALUE_ERROR (next_promise))
{
ret = next_promise;
break;
}
/* j. */
ecma_value_t then_result = ecma_promise_then (next_promise, resolve, reject);
ecma_free_value (next_promise);
/* k. */
if (ECMA_IS_VALUE_ERROR (then_result))
{
ret = then_result;
break;
}
ecma_free_value (then_result);
}
ecma_free_value (reject);
ecma_free_value (resolve);
ecma_deref_ecma_string (str_promise);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
JERRY_ASSERT (!ecma_is_value_empty (ret));
return ret;
} /* ecma_builtin_promise_do_race */
/**
* Helper function for increase or decrease the remaining count.
*
* @return the current remaining count after increase or decrease.
*/
static ecma_length_t
ecma_builtin_promise_remaining_inc_or_dec (ecma_value_t remaining, /**< the remaining count */
bool is_inc) /**< whether to increase the count */
{
JERRY_ASSERT (ecma_is_value_object (remaining));
ecma_object_t *remaining_p = ecma_get_object_from_value (remaining);
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) remaining_p;
JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_NUMBER_UL);
JERRY_ASSERT (ecma_is_value_integer_number (ext_object_p->u.class_prop.u.value));
ecma_length_t current = (ecma_length_t) ecma_get_integer_from_value (ext_object_p->u.class_prop.u.value);
if (is_inc)
{
current++;
}
else
{
current--;
}
ext_object_p->u.class_prop.u.value = ecma_make_uint32_value (current);
return current;
} /* ecma_builtin_promise_remaining_inc_or_dec */
/**
* Native handler for Promise.all Resolve Element Function.
*
* See also:
* ES2015 25.4.4.1.2
*
* @return ecma value of undefined.
*/
static ecma_value_t
ecma_builtin_promise_all_handler (const ecma_value_t function, /**< the function itself */
const ecma_value_t this, /**< this_arg of the function */
const ecma_value_t argv[], /**< argument list */
const ecma_length_t argc) /**< argument number */
{
JERRY_UNUSED (this);
JERRY_UNUSED (argc);
ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
/* 1. */
ecma_object_t *function_p = ecma_get_object_from_value (function);
ecma_string_t *str_already_called = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_ALREADY_CALLED);
ecma_value_t already_called = ecma_op_object_get (function_p, str_already_called);
JERRY_ASSERT (ecma_is_value_boolean (already_called));
/* 2. */
if (ecma_is_value_true (already_called))
{
ecma_fast_free_value (already_called);
ecma_deref_ecma_string (str_already_called);
return ret;
}
/* 3. */
ecma_op_object_put (function_p,
str_already_called,
ecma_make_boolean_value (true),
false);
ecma_string_t *str_index = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_INDEX);
ecma_string_t *str_value = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_VALUE);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_remaining = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT);
/* 4-7. */
ecma_value_t index_val = ecma_op_object_get (function_p, str_index);
ecma_value_t value_array = ecma_op_object_get (function_p, str_value);
ecma_value_t capability = ecma_op_object_get (function_p, str_capability);
ecma_value_t remaining = ecma_op_object_get (function_p, str_remaining);
JERRY_ASSERT (ecma_is_value_integer_number (index_val));
/* 8. */
ecma_string_t *index_str = ecma_new_ecma_string_from_uint32 ((uint32_t) ecma_get_integer_from_value (index_val));
ecma_op_object_put (ecma_get_object_from_value (value_array),
index_str,
argv[0],
false);
ecma_deref_ecma_string (index_str);
/* 9-10. */
if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
{
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability),
str_resolve);
ecma_deref_ecma_string (str_resolve);
ret = ecma_op_function_call (ecma_get_object_from_value (resolve),
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
&value_array,
1);
ecma_free_value (resolve);
}
ecma_free_value (remaining);
ecma_free_value (capability);
ecma_free_value (value_array);
ecma_fast_free_value (index_val);
ecma_fast_free_value (already_called);
ecma_deref_ecma_string (str_already_called);
ecma_deref_ecma_string (str_index);
ecma_deref_ecma_string (str_value);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_remaining);
return ret;
} /* ecma_builtin_promise_all_handler */
/**
* Runtime Semantics: PerformPromiseAll.
*
* See also:
* ES2015 25.4.4.1.1
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
inline static ecma_value_t
ecma_builtin_promise_do_all (ecma_value_t array, /**< the array for all */
ecma_value_t capability, /**< PromiseCapability record */
ecma_value_t ctor) /**< the caller of Promise.race */
{
JERRY_ASSERT (ecma_is_value_object (capability)
&& ecma_is_value_object (array)
&& ecma_is_value_object (ctor));
JERRY_ASSERT (ecma_get_object_builtin_id (ecma_get_object_from_value (ctor)) == ECMA_BUILTIN_ID_PROMISE);
JERRY_ASSERT (ecma_get_object_type (ecma_get_object_from_value (array)) == ECMA_OBJECT_TYPE_ARRAY);
ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
ecma_string_t *magic_string_length_p = ecma_new_ecma_length_string ();
ecma_object_t *array_p = ecma_get_object_from_value (array);
ecma_value_t len_value = ecma_op_object_get (array_p, magic_string_length_p);
ecma_deref_ecma_string (magic_string_length_p);
ecma_length_t len = (ecma_length_t) ecma_get_integer_from_value (len_value);
ecma_fast_free_value (len_value);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
ecma_string_t *str_already_called = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_ALREADY_CALLED);
ecma_string_t *str_index = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_INDEX);
ecma_string_t *str_value = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_VALUE);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_remaining = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT);
ecma_value_t undefined_val = ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
/* String '1' indicates [[Resolve]] and '2' indicates [[Reject]]. */
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability),
str_resolve);
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability),
str_reject);
/* 3. */
ecma_value_t result_array_length_val = ecma_make_uint32_value (0);
ecma_value_t value_array = ecma_op_create_array_object (&result_array_length_val, 1, true);
ecma_free_value (result_array_length_val);
/* 4. */
ecma_value_t remaining = ecma_op_create_number_object (ecma_make_integer_value (1));
/* 5. */
ecma_length_t index = 0;
/* 6 */
while (true)
{
JERRY_ASSERT (index <= len);
/* d. */
if (index == len)
{
/* ii. */
if (ecma_builtin_promise_remaining_inc_or_dec (remaining, false) == 0)
{
/* iii. */
ecma_value_t resolve_ret = ecma_op_function_call (ecma_get_object_from_value (resolve),
ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED),
&value_array,
1);
if (ECMA_IS_VALUE_ERROR (resolve_ret))
{
ret = resolve_ret;
break;
}
}
/* iv. */
ret = ecma_op_object_get (ecma_get_object_from_value (capability), str_promise);
break;
}
/* e. h. */
ecma_string_t *index_str = ecma_new_ecma_string_from_uint32 (index);
ecma_value_t array_item = ecma_op_object_get (array_p, index_str);
ecma_op_object_put (ecma_get_object_from_value (value_array),
index_str,
undefined_val,
false);
ecma_deref_ecma_string (index_str);
/* i. */
ecma_value_t next_promise = ecma_builtin_promise_resolve (ctor, array_item);
ecma_free_value (array_item);
/* j. */
if (ECMA_IS_VALUE_ERROR (next_promise))
{
ret = next_promise;
break;
}
/* k. */
ecma_object_t *res_ele_p;
res_ele_p = ecma_op_create_external_function_object ((ecma_external_pointer_t) ecma_builtin_promise_all_handler);
/* l. */
ecma_op_object_put (res_ele_p,
str_already_called,
ecma_make_boolean_value (false),
false);
/* m. */
ecma_op_object_put (res_ele_p,
str_index,
ecma_make_uint32_value (index),
false);
/* n. */
ecma_op_object_put (res_ele_p,
str_value,
value_array,
false);
/* o. */
ecma_op_object_put (res_ele_p,
str_capability,
capability,
false);
/* p. */
ecma_op_object_put (res_ele_p,
str_remaining,
remaining,
false);
/* q. */
ecma_builtin_promise_remaining_inc_or_dec (remaining, true);
/* r. */
ecma_value_t then_result = ecma_promise_then (next_promise,
ecma_make_object_value (res_ele_p),
reject);
ecma_deref_object (res_ele_p);
ecma_free_value (next_promise);
/* s. */
if (ECMA_IS_VALUE_ERROR (then_result))
{
ret = then_result;
break;
}
ecma_free_value (then_result);
index ++;
}
ecma_free_value (reject);
ecma_free_value (resolve);
ecma_free_value (remaining);
ecma_free_value (value_array);
ecma_deref_ecma_string (str_already_called);
ecma_deref_ecma_string (str_index);
ecma_deref_ecma_string (str_value);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_remaining);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
ecma_deref_ecma_string (str_promise);
JERRY_ASSERT (!ecma_is_value_empty (ret));
return ret;
} /* ecma_builtin_promise_do_all */
/**
* The common function for both Promise.race and Promise.all.
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_race_or_all (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t array, /**< the items to be resolved */
bool is_race) /**< indicates whether it is race function */
{
if (!ecma_is_value_object (this_arg))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not an object."));
}
uint8_t builtin_id = ecma_get_object_builtin_id (ecma_get_object_from_value (this_arg));
if (builtin_id != ECMA_BUILTIN_ID_PROMISE)
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not the Promise constructor."));
}
ecma_value_t capability = ecma_promise_new_capability ();
ecma_value_t ret = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
if (!ecma_is_value_object (array)
|| ecma_get_object_type (ecma_get_object_from_value (array)) != ECMA_OBJECT_TYPE_ARRAY)
{
ecma_value_t error = ecma_raise_type_error (ECMA_ERR_MSG ("Second argument is not an array."));
ret = ecma_builtin_promise_reject_abrupt (error, capability);
ecma_free_value (error);
ecma_free_value (capability);
return ret;
}
if (is_race)
{
ret = ecma_builtin_promise_do_race (array, capability, this_arg);
}
else
{
ret = ecma_builtin_promise_do_all (array, capability, this_arg);
}
if (ECMA_IS_VALUE_ERROR (ret))
{
ret = ecma_get_value_from_error_value (ret);
}
ecma_free_value (capability);
return ret;
} /* ecma_builtin_promise_race_or_all */
/**
* The Promise.race routine.
*
* See also:
* ES2015 25.4.4.3
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_race (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t array) /**< the items to be resolved */
{
return ecma_builtin_promise_race_or_all (this_arg, array, true);
} /* ecma_builtin_promise_race */
/**
* The Promise.all routine.
*
* See also:
* ES2015 25.4.4.1
*
* @return ecma value of the new promise.
* Returned value must be freed with ecma_free_value.
*/
static ecma_value_t
ecma_builtin_promise_all (ecma_value_t this_arg, /**< 'this' argument */
ecma_value_t array) /**< the items to be resolved */
{
return ecma_builtin_promise_race_or_all (this_arg, array, false);
} /* ecma_builtin_promise_all */
/**
* Handle calling [[Call]] of built-in Promise object.
*

View File

@ -19,6 +19,8 @@
#include "ecma-builtin-helpers-macro-defines.inc.h"
#ifndef CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
/* Number properties:
* (property name, number value, writable, enumerable, configurable) */
@ -35,5 +37,11 @@ OBJECT_VALUE (LIT_MAGIC_STRING_PROTOTYPE,
/* Routine properties:
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
ROUTINE (LIT_MAGIC_STRING_REJECT, ecma_builtin_promise_reject, 1, 1)
ROUTINE (LIT_MAGIC_STRING_RESOLVE, ecma_builtin_promise_resolve, 1, 1)
ROUTINE (LIT_MAGIC_STRING_RACE, ecma_builtin_promise_race, 1, 1)
ROUTINE (LIT_MAGIC_STRING_ALL, ecma_builtin_promise_all, 1, 1)
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
#include "ecma-builtin-helpers-macro-undefs.inc.h"

View File

@ -136,13 +136,15 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
ecma_job_promise_reaction_t *job_p = (ecma_job_promise_reaction_t *) obj_p;
ecma_object_t *reaction_p = ecma_get_object_from_value (job_p->reaction);
ecma_string_t *str_0 = ecma_new_ecma_string_from_uint32 (0);
ecma_string_t *str_1 = ecma_new_ecma_string_from_uint32 (1);
ecma_string_t *str_2 = ecma_new_ecma_string_from_uint32 (2);
/* 2. string '0' indicates the [[Capability]] of reaction. */
ecma_value_t capability = ecma_op_object_get (reaction_p, str_0);
/* 3. string '1' indicates the [[Handler]] of reaction. */
ecma_value_t handler = ecma_op_object_get (reaction_p, str_1);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_handler = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_HANDLER);
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
/* 2. */
ecma_value_t capability = ecma_op_object_get (reaction_p, str_capability);
/* 3. */
ecma_value_t handler = ecma_op_object_get (reaction_p, str_handler);
JERRY_ASSERT (ecma_is_value_boolean (handler) || ecma_op_is_callable (handler));
@ -166,9 +168,13 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
if (ecma_is_value_false (handler) || ECMA_IS_VALUE_ERROR (handler_result))
{
/* 7. String '2' indicates [[Reject]] of Capability. */
handler_result = ecma_get_value_from_error_value (handler_result);
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_2);
if (ECMA_IS_VALUE_ERROR (handler_result))
{
handler_result = ecma_get_value_from_error_value (handler_result);
}
/* 7. */
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject);
JERRY_ASSERT (ecma_op_is_callable (reject));
@ -180,8 +186,8 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
}
else
{
/* 8. String '1' indicates [[Resolve]] of Capability. */
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_1);
/* 8. */
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_resolve);
JERRY_ASSERT (ecma_op_is_callable (resolve));
@ -195,9 +201,10 @@ ecma_process_promise_reaction_job (void *obj_p) /**< the job to be operated */
ecma_free_value (handler_result);
ecma_free_value (handler);
ecma_free_value (capability);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_1);
ecma_deref_ecma_string (str_2);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_handler);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
ecma_free_promise_reaction_job (job_p);
return status;

View File

@ -344,54 +344,55 @@ ecma_call_builtin_executor (ecma_object_t *executor_p, /**< the executor object
ecma_value_t resolve_func, /**< the resolve function */
ecma_value_t reject_func) /**< the reject function */
{
ecma_string_t *str_0 = ecma_new_ecma_string_from_uint32 (0);
ecma_string_t *str_1 = ecma_new_ecma_string_from_uint32 (1);
ecma_string_t *str_2 = ecma_new_ecma_string_from_uint32 (2);
/* 2. String '0' indicates [[Capability]] of the executor. */
ecma_value_t capability = ecma_op_object_get (executor_p, str_0);
/* 3. String '1' indicates [[Resolve]] of the capability. */
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_1);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
/* 2. */
ecma_value_t capability = ecma_op_object_get (executor_p, str_capability);
/* 3. */
ecma_value_t resolve = ecma_op_object_get (ecma_get_object_from_value (capability), str_resolve);
if (resolve != ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED))
{
ecma_free_value (resolve);
ecma_free_value (capability);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_1);
ecma_deref_ecma_string (str_2);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
return ecma_raise_type_error (ECMA_ERR_MSG ("'resolve' function should be undefined."));
}
/* 4. String '2' indicates [[Reject]] of the capability. */
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_2);
/* 4. */
ecma_value_t reject = ecma_op_object_get (ecma_get_object_from_value (capability), str_reject);
if (reject != ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED))
{
ecma_free_value (reject);
ecma_free_value (capability);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_1);
ecma_deref_ecma_string (str_2);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
return ecma_raise_type_error (ECMA_ERR_MSG ("'reject' function should be undefined."));
}
/* 5. */
ecma_op_object_put (ecma_get_object_from_value (capability),
str_1,
str_resolve,
resolve_func,
false);
/* 6. */
ecma_op_object_put (ecma_get_object_from_value (capability),
str_2,
str_reject,
reject_func,
false);
ecma_free_value (capability);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_1);
ecma_deref_ecma_string (str_2);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_resolve);
ecma_deref_ecma_string (str_reject);
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED);
} /* ecma_call_builtin_executor */
@ -558,29 +559,30 @@ ecma_promise_new_capability (void)
{
/* 3. */
ecma_object_t *capability_p = ecma_op_create_object_object_noarg ();
ecma_string_t *str_0 = ecma_new_ecma_string_from_uint32 (0);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
/* 4. */
ecma_object_t *executor_p;
executor_p = ecma_op_create_object_object_noarg ();
ecma_value_t executor = ecma_make_object_value (executor_p);
/* 5. String '0' here indicates the [[Capability]] of executor. */
/* 5. */
ecma_op_object_put (executor_p,
str_0,
str_capability,
ecma_make_object_value (capability_p),
false);
/* 6. */
ecma_value_t promise = ecma_op_create_promise_object (executor, false);
/* 10. String '0' here indicates the [[Promise]] of Capability. */
/* 10. */
ecma_op_object_put (capability_p,
str_0,
str_promise,
promise,
false);
ecma_deref_object (executor_p);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_promise);
ecma_deref_ecma_string (str_capability);
/* 7. */
if (ECMA_IS_VALUE_ERROR (promise))
{
@ -590,10 +592,10 @@ ecma_promise_new_capability (void)
}
ecma_free_value (promise);
/* 8. str '1' indicates [[Resolve]] of Capability. */
ecma_string_t *str_1 = ecma_new_ecma_string_from_uint32 (1);
ecma_value_t resolve = ecma_op_object_get (capability_p, str_1);
ecma_deref_ecma_string (str_1);
/* 8. */
ecma_string_t *str_resolve = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_RESOLVE);
ecma_value_t resolve = ecma_op_object_get (capability_p, str_resolve);
ecma_deref_ecma_string (str_resolve);
if (!ecma_op_is_callable (resolve))
{
@ -603,10 +605,10 @@ ecma_promise_new_capability (void)
}
ecma_free_value (resolve);
/* 9. str '2' indicates [[Reject]] of Capability. */
ecma_string_t *str_2 = ecma_new_ecma_string_from_uint32 (2);
ecma_value_t reject = ecma_op_object_get (capability_p, str_2);
ecma_deref_ecma_string (str_2);
/* 9. */
ecma_string_t *str_reject = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_REJECT);
ecma_value_t reject = ecma_op_object_get (capability_p, str_reject);
ecma_deref_ecma_string (str_reject);
if (!ecma_op_is_callable (reject))
{
@ -629,14 +631,15 @@ ecma_promise_new_capability (void)
* @return ecma value of the new promise object
* Returned value must be freed with ecma_free_value
*/
ecma_value_t
ecma_promise_then (ecma_value_t promise, /**< the promise which call 'then' */
ecma_value_t on_fulfilled, /**< on_fulfilled function */
ecma_value_t on_rejected, /**< on_rejected function */
ecma_value_t result_capability) /**< promise capability */
static ecma_value_t
ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' */
ecma_value_t on_fulfilled, /**< on_fulfilled function */
ecma_value_t on_rejected, /**< on_rejected function */
ecma_value_t result_capability) /**< promise capability */
{
ecma_string_t *str_0 = ecma_new_ecma_string_from_uint32 (0);
ecma_string_t *str_1 = ecma_new_ecma_string_from_uint32 (1);
ecma_string_t *str_capability = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_CAPABILITY);
ecma_string_t *str_handler = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_HANDLER);
ecma_string_t *str_promise = ecma_new_ecma_string_from_uint32 (ECMA_PROMISE_PROPERTY_PROMISE);
/* 3. boolean true indicates "indentity" */
if (!ecma_op_is_callable (on_fulfilled))
@ -650,24 +653,24 @@ ecma_promise_then (ecma_value_t promise, /**< the promise which call 'then' */
on_rejected = ecma_make_boolean_value (false);
}
/* 5-6. String '0' indicates [[Capability]] of a PromiseReaction, '1' indicates [[Handler]]. */
/* 5-6. */
ecma_object_t *fulfill_reaction_p = ecma_op_create_object_object_noarg ();
ecma_object_t *reject_reaction_p = ecma_op_create_object_object_noarg ();
ecma_op_object_put (fulfill_reaction_p,
str_0,
str_capability,
result_capability,
false);
ecma_op_object_put (fulfill_reaction_p,
str_1,
str_handler,
on_fulfilled,
false);
ecma_op_object_put (reject_reaction_p,
str_0,
str_capability,
result_capability,
false);
ecma_op_object_put (reject_reaction_p,
str_1,
str_handler,
on_rejected,
false);
@ -700,13 +703,45 @@ ecma_promise_then (ecma_value_t promise, /**< the promise which call 'then' */
ecma_free_value (reason);
}
/* 10. String '0' indicates [[Promise]] of a Capability. */
ecma_value_t ret = ecma_op_object_get (ecma_get_object_from_value (result_capability), str_0);
/* 10. */
ecma_value_t ret = ecma_op_object_get (ecma_get_object_from_value (result_capability), str_promise);
ecma_deref_object (fulfill_reaction_p);
ecma_deref_object (reject_reaction_p);
ecma_deref_ecma_string (str_0);
ecma_deref_ecma_string (str_1);
ecma_deref_ecma_string (str_capability);
ecma_deref_ecma_string (str_handler);
ecma_deref_ecma_string (str_promise);
return ret;
} /* ecma_promise_do_then */
/**
* The common function for ecma_builtin_promise_prototype_then
* and ecma_builtin_promise_prototype_catch.
*
* @return ecma value of a new promise object.
* Returned value must be freed with ecma_free_value.
*/
ecma_value_t
ecma_promise_then (ecma_value_t promise, /**< the promise which call 'then' */
ecma_value_t on_fulfilled, /**< on_fulfilled function */
ecma_value_t on_rejected) /**< on_rejected function */
{
ecma_object_t *obj = ecma_get_object_from_value (promise);
if (!ecma_is_promise (obj))
{
return ecma_raise_type_error (ECMA_ERR_MSG ("'this' is not a Promise."));
}
ecma_value_t result_capability = ecma_promise_new_capability ();
if (ECMA_IS_VALUE_ERROR (result_capability))
{
return result_capability;
}
ecma_value_t ret = ecma_promise_do_then (promise, on_fulfilled, on_rejected, result_capability);
ecma_free_value (result_capability);
return ret;
} /* ecma_promise_then */

View File

@ -58,6 +58,23 @@ typedef struct
ecma_collection_header_t *reject_reactions; /**< list of PromiseRejectReactions */
} ecma_promise_object_t;
/**
* Use symbolic constant to represent the internal property name of
* promise related structures.
*/
typedef enum
{
ECMA_PROMISE_PROPERTY_PROMISE, /**< [[Promise]] property */
ECMA_PROMISE_PROPERTY_RESOLVE, /**< [[Resolve]] property */
ECMA_PROMISE_PROPERTY_REJECT, /**< [[Reject]] property */
ECMA_PROMISE_PROPERTY_CAPABILITY, /**< [[Capability]] property */
ECMA_PROMISE_PROPERTY_HANDLER, /**< [[Handler]] property */
ECMA_PROMISE_PROPERTY_ALREADY_CALLED, /**< [[AlreadyCalled]] property */
ECMA_PROMISE_PROPERTY_INDEX, /**< [[Index]] property */
ECMA_PROMISE_PROPERTY_VALUE, /**< [[Values]] property */
ECMA_PROMISE_PROPERTY_REMAINING_ELEMENT /**< [[RemainingElement]] property */
} ecma_promise_property_symbolic_constant_t;
bool ecma_is_promise (ecma_object_t *obj_p);
ecma_value_t ecma_promise_get_result (ecma_object_t *obj_p);
void ecma_promise_set_result (ecma_object_t *obj_p, ecma_value_t result);
@ -72,8 +89,8 @@ ecma_value_t ecma_promise_new_capability (void);
ecma_value_t
ecma_promise_then (ecma_value_t promise,
ecma_value_t on_fulfilled,
ecma_value_t on_rejected,
ecma_value_t result_capability);
ecma_value_t on_rejected);
/**
* @}
* @}

View File

@ -63,6 +63,11 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UTC_U, "UTC")
#endif
#if !defined (CONFIG_DISABLE_MATH_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ABS, "abs")
#endif
#if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ALL, "all")
#endif
#if !defined (CONFIG_DISABLE_MATH_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_COS, "cos")
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EXP, "exp")
#endif
@ -130,6 +135,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_NULL, "null")
#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_PUSH, "push")
#endif
#if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RACE, "race")
#endif
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SEAL, "seal")
#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
@ -161,6 +169,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_APPLY, "apply")
#if !defined (CONFIG_DISABLE_MATH_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ATAN2, "atan2")
#endif
#if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_CATCH, "catch")
#endif
#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_EVERY, "every")
@ -244,6 +255,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RANDOM, "random")
|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REDUCE, "reduce")
#endif
#if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REJECT, "reject")
#endif
#if !defined (CONFIG_DISABLE_REGEXP_BUILTIN) && !defined (CONFIG_DISABLE_STRING_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_SEARCH, "search")
#endif
@ -294,6 +308,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_MESSAGE, "message")
#if !defined (CONFIG_DISABLE_REGEXP_BUILTIN) && !defined (CONFIG_DISABLE_STRING_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REPLACE, "replace")
#endif
#if !defined (CONFIG_DISABLE_ES2015_PROMISE_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_RESOLVE, "resolve")
#endif
#if !defined (CONFIG_DISABLE_ARRAY_BUILTIN) \
|| !defined (CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN)
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_REVERSE, "reverse")

View File

@ -47,6 +47,7 @@ LIT_MAGIC_STRING_LN2_U = "LN2"
LIT_MAGIC_STRING_NAN = "NaN"
LIT_MAGIC_STRING_UTC_U = "UTC"
LIT_MAGIC_STRING_ABS = "abs"
LIT_MAGIC_STRING_ALL = "all"
LIT_MAGIC_STRING_COS = "cos"
LIT_MAGIC_STRING_EXP = "exp"
LIT_MAGIC_STRING_GET = "get"
@ -80,6 +81,7 @@ LIT_MAGIC_STRING_KEYS = "keys"
LIT_MAGIC_STRING_NAME = "name"
LIT_MAGIC_STRING_NULL = "null"
LIT_MAGIC_STRING_PUSH = "push"
LIT_MAGIC_STRING_RACE = "race"
LIT_MAGIC_STRING_SEAL = "seal"
LIT_MAGIC_STRING_SOME = "some"
LIT_MAGIC_STRING_SORT = "sort"
@ -94,6 +96,7 @@ LIT_MAGIC_STRING_LOG2E_U = "LOG2E"
LIT_MAGIC_STRING_SQRT2_U = "SQRT2"
LIT_MAGIC_STRING_APPLY = "apply"
LIT_MAGIC_STRING_ATAN2 = "atan2"
LIT_MAGIC_STRING_CATCH = "catch"
LIT_MAGIC_STRING_EVERY = "every"
LIT_MAGIC_STRING_FALSE = "false"
LIT_MAGIC_STRING_FLOOR = "floor"
@ -130,6 +133,7 @@ LIT_MAGIC_STRING_NUMBER = "number"
LIT_MAGIC_STRING_OBJECT = "object"
LIT_MAGIC_STRING_RANDOM = "random"
LIT_MAGIC_STRING_REDUCE = "reduce"
LIT_MAGIC_STRING_REJECT = "reject"
LIT_MAGIC_STRING_SEARCH = "search"
LIT_MAGIC_STRING_SOURCE = "source"
LIT_MAGIC_STRING_SPLICE = "splice"
@ -149,6 +153,7 @@ LIT_MAGIC_STRING_INDEX_OF_UL = "indexOf"
LIT_MAGIC_STRING_IS_ARRAY_UL = "isArray"
LIT_MAGIC_STRING_MESSAGE = "message"
LIT_MAGIC_STRING_REPLACE = "replace"
LIT_MAGIC_STRING_RESOLVE = "resolve"
LIT_MAGIC_STRING_REVERSE = "reverse"
LIT_MAGIC_STRING_SET_DATE_UL = "setDate"
LIT_MAGIC_STRING_SET_TIME_UL = "setTime"

View File

@ -13,4 +13,7 @@
* limitations under the License.
*/
assert (Promise.prototype.length === 1);
Promise.resolve("abc").then(function(x)
{
assert (x === "abc");
});

View File

@ -13,24 +13,13 @@
* limitations under the License.
*/
var obj = {name:""};
var a = new Promise(function(f)
{
var o = {name: "abc"};
f(o);
})
var a = new Promise(function(f, r){
obj.name = obj.name + "a";
f(obj);
Promise.resolve(a).then(function(x)
{
assert (x.name === "abc");
});
a.then(function(x) {
x.name = x.name + "b";
return x;
}).then(null, function(x) {
x.name = x.name + "c"; // unreachable
return x;
}).then(function(x) {
x.name = x.name + "d";
assert (obj.name === "aebd");
});
obj.name = obj.name + "e";
assert (obj.name === "ae")

View File

@ -13,24 +13,10 @@
* limitations under the License.
*/
var a = new Promise(function(f, r){
r(0);
Promise.reject("abc").then(function(x)
{
assert (false); // should not run here.
}, function(x)
{
assert (x === "abc");
});
a
.then(function f1(x) {
return x + 1; // unreachable
}, function r1(x){
return x + 10;
})
.then(function f2(x) {
throw x + 100
})
.then(function f3(x) {
return x + 1000 //unreachable
}, function r3(x) {
return x + 10000
})
.then(function(x) {
assert (x === 10110);
})

View File

@ -13,14 +13,37 @@
* limitations under the License.
*/
var a = new Promise(function(f, r){
f("a");
var a = Promise.resolve('a');
var b = Promise.reject('b');
Promise.race([a, b]).then(function(x)
{
assert (x === 'a');
}, function(x)
{
assert (false); // should not run here.
});
var b = new Promise(function(f, r){
f(a);
})
Promise.race([b, a]).then(function(x)
{
assert (false); // should not run here.
}, function(x)
{
assert (x === 'b');
});
b.then(function(x) {
assert (x === "a");
})
Promise.race([ ,b, a]).then(function(x)
{
assert (x === undefined);
}, function(x)
{
assert (false); // should not run here.
});
Promise.race(a).then(function(x)
{
assert (false); // should not run here.
}, function(x)
{
assert(x.name === "TypeError");
});

View File

@ -0,0 +1,52 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var a = Promise.resolve('a');
var b = Promise.resolve('b');
var c = Promise.reject('c');
Promise.all([a, b, 1]).then(function(x)
{
assert (x[0] === 'a');
assert (x[1] === 'b');
assert (x[2] === 1);
}, function(x)
{
assert (false); // should not run here.
});
Promise.all([a, b, c, 1]).then(function(x)
{
assert (false); // should not run here.
}, function(x)
{
assert (x === 'c');
});
Promise.all([]).then(function(x)
{
assert (x.length === 0);
}, function(x)
{
assert (false); // should not run here.
});
Promise.all(a).then(function(x)
{
assert (false); // should not run here.
}, function(x)
{
assert(x.name === "TypeError");
});

View File

@ -0,0 +1,16 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
assert (Promise.prototype.length === 1);

View File

@ -0,0 +1,36 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var obj = {name:""};
var a = new Promise(function(f, r){
obj.name = obj.name + "a";
f(obj);
});
a.then(function(x) {
x.name = x.name + "b";
return x;
}).then(null, function(x) {
x.name = x.name + "c"; // unreachable
return x;
}).then(function(x) {
x.name = x.name + "d";
assert (obj.name === "aebd");
});
obj.name = obj.name + "e";
assert (obj.name === "ae")

View File

@ -0,0 +1,36 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var a = new Promise(function(f, r){
r(0);
});
a
.then(function f1(x) {
return x + 1; // unreachable
}, function r1(x){
return x + 10;
})
.then(function f2(x) {
throw x + 100
})
.then(function f3(x) {
return x + 1000 //unreachable
}, function r3(x) {
return x + 10000
})
.then(function(x) {
assert (x === 10110);
})

View File

@ -0,0 +1,26 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
var a = new Promise(function(f, r){
f("a");
});
var b = new Promise(function(f, r){
f(a);
})
b.then(function(x) {
assert (x === "a");
})

View File

@ -0,0 +1,22 @@
/* Copyright JS Foundation and other contributors, http://js.foundation
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
Promise.reject("abc").catch(function(x)
{
assert (x === "abc");
return "def";
}).then(function(x) {
assert (x === "def");
});

View File

@ -0,0 +1,15 @@
// Copyright JS Foundation and other contributors, http://js.foundation
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
new Promise(Math.max.propertyIsEnumerable.toString).then()