@@ -161,6 +161,37 @@ ecma_promise_trigger_reactions (ecma_collection_t *reactions, /**< lists of reac
161161 }
162162} /* ecma_promise_trigger_reactions */
163163
164+ static bool
165+ ecma_is_resolver_already_called (ecma_object_t * resolver_p , /**< resolver */
166+ ecma_object_t * promise_obj_p ) /**< promise */
167+ {
168+ ecma_string_t * str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED );
169+ ecma_property_t * property_p = ecma_find_named_property (resolver_p , str_already_resolved_p );
170+
171+ if (property_p == NULL )
172+ {
173+ return (ecma_promise_get_flags (promise_obj_p ) & ECMA_PROMISE_ALREADY_RESOLVED ) != 0 ;
174+ }
175+
176+ JERRY_ASSERT (ECMA_PROPERTY_GET_TYPE (* property_p ) == ECMA_PROPERTY_TYPE_NAMEDDATA );
177+
178+ ecma_value_t already_resolved = ECMA_PROPERTY_VALUE_PTR (property_p )-> value ;
179+
180+ ecma_object_t * object_p = ecma_get_object_from_value (already_resolved );
181+
182+ JERRY_ASSERT (ecma_get_object_type (object_p ) == ECMA_OBJECT_TYPE_CLASS );
183+
184+ ecma_extended_object_t * already_resolved_p = (ecma_extended_object_t * ) object_p ;
185+
186+ JERRY_ASSERT (already_resolved_p -> u .class_prop .class_id == LIT_MAGIC_STRING_BOOLEAN_UL );
187+
188+ ecma_value_t current_value = already_resolved_p -> u .class_prop .u .value ;
189+
190+ already_resolved_p -> u .class_prop .u .value = ECMA_VALUE_TRUE ;
191+
192+ return current_value == ECMA_VALUE_TRUE ;
193+ } /* ecma_is_resolver_already_called */
194+
164195/**
165196 * Reject a Promise with a reason.
166197 *
@@ -242,10 +273,9 @@ ecma_promise_reject_handler (const ecma_value_t function, /**< the function itse
242273 JERRY_ASSERT (ecma_is_promise (promise_obj_p ));
243274
244275 /* 3., 4. */
245- if (ecma_promise_get_flags ( promise_obj_p ) & ECMA_PROMISE_ALREADY_RESOLVED )
276+ if (ecma_is_resolver_already_called ( function_p , promise_obj_p ))
246277 {
247- ecma_free_value (promise );
248- return ECMA_VALUE_UNDEFINED ;
278+ goto end_of_resolve_function ;
249279 }
250280
251281 /* 5. */
@@ -254,6 +284,8 @@ ecma_promise_reject_handler (const ecma_value_t function, /**< the function itse
254284 /* 6. */
255285 ecma_value_t reject_value = (argc == 0 ) ? ECMA_VALUE_UNDEFINED : argv [0 ];
256286 ecma_reject_promise (promise , reject_value );
287+
288+ end_of_resolve_function :
257289 ecma_free_value (promise );
258290 return ECMA_VALUE_UNDEFINED ;
259291} /* ecma_promise_reject_handler */
@@ -281,7 +313,7 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
281313 JERRY_ASSERT (ecma_is_promise (promise_obj_p ));
282314
283315 /* 3., 4. */
284- if (ecma_promise_get_flags ( promise_obj_p ) & ECMA_PROMISE_ALREADY_RESOLVED )
316+ if (ecma_is_resolver_already_called ( function_p , promise_obj_p ))
285317 {
286318 goto end_of_resolve_function ;
287319 }
@@ -428,7 +460,8 @@ ecma_promise_create_resolving_functions_helper (ecma_object_t *obj_p, /**< Promi
428460 */
429461void
430462ecma_promise_create_resolving_functions (ecma_object_t * object_p , /**< the promise object */
431- ecma_promise_resolving_functions_t * funcs ) /**< [out] resolving functions */
463+ ecma_promise_resolving_functions_t * funcs , /**< [out] resolving functions */
464+ bool create_already_resolved ) /**< create already resolved flag */
432465{
433466 /* 2. - 4. */
434467 funcs -> resolve = ecma_promise_create_resolving_functions_helper (object_p ,
@@ -437,6 +470,28 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p, /**< the promi
437470 /* 5. - 7. */
438471 funcs -> reject = ecma_promise_create_resolving_functions_helper (object_p ,
439472 ecma_promise_reject_handler );
473+ if (!create_already_resolved )
474+ {
475+ return ;
476+ }
477+
478+ ecma_value_t already_resolved = ecma_op_create_boolean_object (ECMA_VALUE_FALSE );
479+ ecma_string_t * str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED );
480+ ecma_property_value_t * value_p ;
481+
482+ value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs -> resolve ),
483+ str_already_resolved_p ,
484+ ECMA_PROPERTY_FIXED ,
485+ NULL );
486+ value_p -> value = already_resolved ;
487+
488+ value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs -> reject ),
489+ str_already_resolved_p ,
490+ ECMA_PROPERTY_FIXED ,
491+ NULL );
492+ value_p -> value = already_resolved ;
493+
494+ ecma_free_value (already_resolved );
440495} /* ecma_promise_create_resolving_functions */
441496
442497/**
@@ -490,7 +545,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
490545 promise_object_p -> reactions = reactions ;
491546 /* 8. */
492547 ecma_promise_resolving_functions_t funcs ;
493- ecma_promise_create_resolving_functions (object_p , & funcs );
548+ ecma_promise_create_resolving_functions (object_p , & funcs , false );
494549
495550 ecma_string_t * str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION );
496551 ecma_string_t * str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION );
0 commit comments