@@ -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,18 +273,16 @@ 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 ;
249- }
278+ /* 5. */
279+ ((ecma_extended_object_t * ) promise_obj_p )-> u .class_prop .extra_info |= ECMA_PROMISE_ALREADY_RESOLVED ;
250280
251- /* 5. */
252- ((ecma_extended_object_t * ) promise_obj_p )-> u .class_prop .extra_info |= ECMA_PROMISE_ALREADY_RESOLVED ;
281+ /* 6. */
282+ ecma_value_t reject_value = (argc == 0 ) ? ECMA_VALUE_UNDEFINED : argv [0 ];
283+ ecma_reject_promise (promise , reject_value );
284+ }
253285
254- /* 6. */
255- ecma_value_t reject_value = (argc == 0 ) ? ECMA_VALUE_UNDEFINED : argv [0 ];
256- ecma_reject_promise (promise , reject_value );
257286 ecma_free_value (promise );
258287 return ECMA_VALUE_UNDEFINED ;
259288} /* ecma_promise_reject_handler */
@@ -281,7 +310,7 @@ ecma_promise_resolve_handler (const ecma_value_t function, /**< the function its
281310 JERRY_ASSERT (ecma_is_promise (promise_obj_p ));
282311
283312 /* 3., 4. */
284- if (ecma_promise_get_flags ( promise_obj_p ) & ECMA_PROMISE_ALREADY_RESOLVED )
313+ if (ecma_is_resolver_already_called ( function_p , promise_obj_p ))
285314 {
286315 goto end_of_resolve_function ;
287316 }
@@ -428,7 +457,8 @@ ecma_promise_create_resolving_functions_helper (ecma_object_t *obj_p, /**< Promi
428457 */
429458void
430459ecma_promise_create_resolving_functions (ecma_object_t * object_p , /**< the promise object */
431- ecma_promise_resolving_functions_t * funcs ) /**< [out] resolving functions */
460+ ecma_promise_resolving_functions_t * funcs , /**< [out] resolving functions */
461+ bool create_already_resolved ) /**< create already resolved flag */
432462{
433463 /* 2. - 4. */
434464 funcs -> resolve = ecma_promise_create_resolving_functions_helper (object_p ,
@@ -437,6 +467,28 @@ ecma_promise_create_resolving_functions (ecma_object_t *object_p, /**< the promi
437467 /* 5. - 7. */
438468 funcs -> reject = ecma_promise_create_resolving_functions_helper (object_p ,
439469 ecma_promise_reject_handler );
470+ if (!create_already_resolved )
471+ {
472+ return ;
473+ }
474+
475+ ecma_value_t already_resolved = ecma_op_create_boolean_object (ECMA_VALUE_FALSE );
476+ ecma_string_t * str_already_resolved_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_ALREADY_RESOLVED );
477+ ecma_property_value_t * value_p ;
478+
479+ value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs -> resolve ),
480+ str_already_resolved_p ,
481+ ECMA_PROPERTY_FIXED ,
482+ NULL );
483+ value_p -> value = already_resolved ;
484+
485+ value_p = ecma_create_named_data_property (ecma_get_object_from_value (funcs -> reject ),
486+ str_already_resolved_p ,
487+ ECMA_PROPERTY_FIXED ,
488+ NULL );
489+ value_p -> value = already_resolved ;
490+
491+ ecma_free_value (already_resolved );
440492} /* ecma_promise_create_resolving_functions */
441493
442494/**
@@ -490,7 +542,7 @@ ecma_op_create_promise_object (ecma_value_t executor, /**< the executor function
490542 promise_object_p -> reactions = reactions ;
491543 /* 8. */
492544 ecma_promise_resolving_functions_t funcs ;
493- ecma_promise_create_resolving_functions (object_p , & funcs );
545+ ecma_promise_create_resolving_functions (object_p , & funcs , false );
494546
495547 ecma_string_t * str_resolve_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_RESOLVE_FUNCTION );
496548 ecma_string_t * str_reject_p = ecma_get_magic_string (LIT_INTERNAL_MAGIC_STRING_REJECT_FUNCTION );
0 commit comments