Skip to content

Commit b39ac3d

Browse files
committed
Introduce jerry_port_track_promise_rejection
This patch resolves #2931. JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
1 parent 363bc92 commit b39ac3d

File tree

8 files changed

+216
-0
lines changed

8 files changed

+216
-0
lines changed

docs/05.PORT-API.md

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,32 @@ jerry_port_get_native_module (jerry_value_t name) /**< module specifier */
151151
}
152152
```
153153
154+
## Promise
155+
156+
```c
157+
/**
158+
* HostPromiseRejectionTracker operations
159+
*/
160+
typedef enum
161+
{
162+
JERRY_PROMISE_REJECTION_OPERATION_REJECT, /**< promise is rejected without any handlers */
163+
JERRY_PROMISE_REJECTION_OPERATION_HANDLE, /**< handler is added to a rejected promise for the first time */
164+
} jerry_promise_rejection_operation_t;
165+
166+
/**
167+
* Track unhandled promise rejections.
168+
*
169+
* Note:
170+
* This port function is called by jerry-core when JERRY_BUILTIN_PROMISE
171+
* is enabled.
172+
*
173+
* @param promise rejected promise
174+
* @param operation HostPromiseRejectionTracker operation
175+
*/
176+
void jerry_port_track_promise_rejection (const jerry_value_t promise,
177+
const jerry_promise_rejection_operation_t operation);
178+
```
179+
154180
## Date
155181

156182
```c
@@ -392,3 +418,33 @@ void jerry_port_sleep (uint32_t sleep_time)
392418
} /* jerry_port_sleep */
393419
#endif /* defined (JERRY_DEBUGGER) && (JERRY_DEBUGGER == 1) */
394420
```
421+
422+
## Promise
423+
424+
```c
425+
#include "jerryscript-port.h"
426+
427+
/**
428+
* Default implementation of jerry_port_track_promise_rejection.
429+
* Prints the reason of the unhandled rejections.
430+
*/
431+
void
432+
jerry_port_track_promise_rejection (const jerry_value_t promise, /**< rejected promise */
433+
const jerry_promise_rejection_operation_t operation) /**< HostPromiseRejectionTracker
434+
* operation */
435+
{
436+
(void) operation; /* unused */
437+
438+
jerry_value_t reason = jerry_get_promise_result (promise);
439+
jerry_value_t reason_to_string = jerry_value_to_string (reason);
440+
jerry_size_t req_sz = jerry_get_utf8_string_size (reason_to_string);
441+
jerry_char_t str_buf_p[req_sz + 1];
442+
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, req_sz);
443+
str_buf_p[req_sz] = '\0';
444+
445+
jerry_release_value (reason_to_string);
446+
jerry_release_value (reason);
447+
448+
printf ("Uncaught (in promise) %s\n", str_buf_p);
449+
} /* jerry_port_track_promise_rejection */
450+
```

jerry-core/ecma/operations/ecma-promise-object.c

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,23 @@ ecma_is_resolver_already_called (ecma_object_t *promise_obj_p) /**< promise */
181181
return (ecma_promise_get_flags (promise_obj_p) & ECMA_PROMISE_ALREADY_RESOLVED) != 0;
182182
} /* ecma_is_resolver_already_called */
183183

184+
/**
185+
* HostPromiseRejectionTracker
186+
*
187+
* See also: ES11 25.6.1.9
188+
*/
189+
static void
190+
ecma_track_promise_rejection (ecma_object_t *obj_p, /**< rejected promise */
191+
jerry_promise_rejection_operation_t operation) /**< HostPromiseRejectionTracker operation */
192+
{
193+
JERRY_ASSERT (ecma_is_promise (obj_p));
194+
195+
if (!(ecma_promise_get_flags (obj_p) & ECMA_PROMISE_HANDLED))
196+
{
197+
jerry_port_track_promise_rejection (ecma_make_object_value (obj_p), operation);
198+
}
199+
} /* ecma_track_promise_rejection */
200+
184201
/**
185202
* Reject a Promise with a reason.
186203
*
@@ -208,6 +225,7 @@ ecma_reject_promise (ecma_value_t promise, /**< promise */
208225
promise_p->reactions = ecma_new_collection ();
209226

210227
ecma_collection_destroy (reactions);
228+
ecma_track_promise_rejection (obj_p, JERRY_PROMISE_REJECTION_OPERATION_REJECT);
211229
} /* ecma_reject_promise */
212230

213231
/**
@@ -818,10 +836,14 @@ ecma_promise_do_then (ecma_value_t promise, /**< the promise which call 'then' *
818836
{
819837
/* 9. */
820838
ecma_value_t reason = ecma_promise_get_result (promise_obj_p);
839+
ecma_track_promise_rejection (promise_obj_p, JERRY_PROMISE_REJECTION_OPERATION_HANDLE);
821840
ecma_enqueue_promise_reaction_job (ecma_make_object_value (result_capability_obj_p), on_rejected, reason);
822841
ecma_free_value (reason);
823842
}
824843

844+
/* ES11: 11. */
845+
promise_p->header.u.class_prop.extra_info |= ECMA_PROMISE_HANDLED;
846+
825847
/* 10. */
826848
return ecma_copy_value (capability_p->header.u.class_prop.u.promise);
827849
} /* ecma_promise_do_then */

jerry-core/ecma/operations/ecma-promise-object.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ typedef enum
3434
ECMA_PROMISE_IS_PENDING = (1 << 0), /**< pending state */
3535
ECMA_PROMISE_IS_FULFILLED = (1 << 1), /**< fulfilled state */
3636
ECMA_PROMISE_ALREADY_RESOLVED = (1 << 2), /**< already resolved */
37+
ECMA_PROMISE_HANDLED = (1 << 3), /**< ES11: 25.6.6 [[PromiseIsHandled]] internal slot */
3738
} ecma_promise_flags_t;
3839

3940
/**

jerry-core/include/jerryscript-port.h

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -252,6 +252,28 @@ size_t jerry_port_normalize_path (const char *in_path_p,
252252
*/
253253
jerry_value_t jerry_port_get_native_module (jerry_value_t name);
254254

255+
/**
256+
* HostPromiseRejectionTracker operations
257+
*/
258+
typedef enum
259+
{
260+
JERRY_PROMISE_REJECTION_OPERATION_REJECT, /**< promise is rejected without any handlers */
261+
JERRY_PROMISE_REJECTION_OPERATION_HANDLE, /**< handler is added to a rejected promise for the first time */
262+
} jerry_promise_rejection_operation_t;
263+
264+
/**
265+
* Track unhandled promise rejections.
266+
*
267+
* Note:
268+
* This port function is called by jerry-core when JERRY_BUILTIN_PROMISE
269+
* is enabled.
270+
*
271+
* @param promise rejected promise
272+
* @param operation HostPromiseRejectionTracker operation
273+
*/
274+
void jerry_port_track_promise_rejection (const jerry_value_t promise,
275+
const jerry_promise_rejection_operation_t operation);
276+
255277
/**
256278
* @}
257279
*/

jerry-port/default/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ set(SOURCE_PORT_DEFAULT
2727
default-fatal.c
2828
default-io.c
2929
default-module.c
30+
default-promise.c
3031
)
3132

3233
# Amalgamated JerryScript source/header build.

jerry-port/default/default-promise.c

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "jerryscript-port.h"
17+
18+
/**
19+
* Default implementation of jerry_port_track_promise_rejection.
20+
* Prints the reason of the unhandled rejections.
21+
*/
22+
void
23+
jerry_port_track_promise_rejection (const jerry_value_t promise, /**< rejected promise */
24+
const jerry_promise_rejection_operation_t operation) /**< HostPromiseRejectionTracker
25+
* operation */
26+
{
27+
(void) operation; /* unused */
28+
29+
jerry_value_t reason = jerry_get_promise_result (promise);
30+
jerry_value_t reason_to_string = jerry_value_to_string (reason);
31+
jerry_size_t req_sz = jerry_get_utf8_string_size (reason_to_string);
32+
JERRY_VLA (jerry_char_t, str_buf_p, req_sz + 1);
33+
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, req_sz);
34+
str_buf_p[req_sz] = '\0';
35+
36+
jerry_release_value (reason_to_string);
37+
jerry_release_value (reason);
38+
39+
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught (in promise) %s\n", str_buf_p);
40+
} /* jerry_port_track_promise_rejection */

targets/esp-idf/promise.c

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Copyright JS Foundation and other contributors, http://js.foundation
2+
*
3+
* Licensed under the Apache License, Version 2.0 (the "License");
4+
* you may not use this file except in compliance with the License.
5+
* You may obtain a copy of the License at
6+
*
7+
* http://www.apache.org/licenses/LICENSE-2.0
8+
*
9+
* Unless required by applicable law or agreed to in writing, software
10+
* distributed under the License is distributed on an "AS IS" BASIS
11+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
* See the License for the specific language governing permissions and
13+
* limitations under the License.
14+
*/
15+
16+
#include "jerryscript-port.h"
17+
18+
/**
19+
* Track unhandled promise rejections.
20+
*
21+
* Note:
22+
* This port function is called by jerry-core when JERRY_BUILTIN_PROMISE
23+
* is enabled.
24+
*
25+
* @param promise rejected promise
26+
* @param operation HostPromiseRejectionTracker operation
27+
*/
28+
void
29+
jerry_port_track_promise_rejection (const jerry_value_t promise,
30+
const jerry_promise_rejection_operation_t operation)
31+
{
32+
(void) operation; /* unused */
33+
34+
jerry_value_t reason = jerry_get_promise_result (promise);
35+
jerry_value_t reason_to_string = jerry_value_to_string (reason);
36+
jerry_size_t req_sz = jerry_get_utf8_string_size (reason_to_string);
37+
jerry_char_t str_buf_p[req_sz + 1];
38+
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, req_sz);
39+
str_buf_p[req_sz] = '\0';
40+
41+
jerry_release_value (reason_to_string);
42+
jerry_release_value (reason);
43+
44+
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught (in promise) %s\n", str_buf_p);
45+
} /* jerry_port_track_promise_rejection */

targets/nuttx-stm32f4/jerry_port.c

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,3 +227,32 @@ jerry_port_get_current_context (void)
227227
{
228228
return current_context_p;
229229
} /* jerry_port_get_current_context */
230+
231+
/**
232+
* Track unhandled promise rejections.
233+
*
234+
* Note:
235+
* This port function is called by jerry-core when JERRY_BUILTIN_PROMISE
236+
* is enabled.
237+
*
238+
* @param promise rejected promise
239+
* @param operation HostPromiseRejectionTracker operation
240+
*/
241+
void
242+
jerry_port_track_promise_rejection (const jerry_value_t promise,
243+
const jerry_promise_rejection_operation_t operation)
244+
{
245+
(void) operation; /* unused */
246+
247+
jerry_value_t reason = jerry_get_promise_result (promise);
248+
jerry_value_t reason_to_string = jerry_value_to_string (reason);
249+
jerry_size_t req_sz = jerry_get_utf8_string_size (reason_to_string);
250+
jerry_char_t str_buf_p[req_sz + 1];
251+
jerry_string_to_utf8_char_buffer (reason_to_string, str_buf_p, req_sz);
252+
str_buf_p[req_sz] = '\0';
253+
254+
jerry_release_value (reason_to_string);
255+
jerry_release_value (reason);
256+
257+
jerry_port_log (JERRY_LOG_LEVEL_WARNING, "Uncaught (in promise) %s\n", str_buf_p);
258+
} /* jerry_port_track_promise_rejection */

0 commit comments

Comments
 (0)