Skip to content

Commit 104001d

Browse files
authored
Implement function name support for script functions and classes (#3745)
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent 562dcc8 commit 104001d

29 files changed

+871
-393
lines changed

jerry-core/api/jerry-snapshot.c

Lines changed: 101 additions & 97 deletions
Large diffs are not rendered by default.

jerry-core/api/jerry.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -429,7 +429,7 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
429429
#if ENABLED (JERRY_PARSER)
430430
jerry_assert_api_available ();
431431

432-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
432+
#if ENABLED (JERRY_RESOURCE_NAME)
433433
if (resource_name_length == 0)
434434
{
435435
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
@@ -439,7 +439,7 @@ jerry_parse (const jerry_char_t *resource_name_p, /**< resource name (usually a
439439
JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p,
440440
(lit_utf8_size_t) resource_name_length);
441441
}
442-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
442+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
443443

444444
ecma_compiled_code_t *bytecode_data_p;
445445
ecma_value_t parse_status;
@@ -507,7 +507,7 @@ jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (u
507507
ecma_compiled_code_t *bytecode_data_p;
508508
ecma_value_t parse_status;
509509

510-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
510+
#if ENABLED (JERRY_RESOURCE_NAME)
511511
if (resource_name_length == 0)
512512
{
513513
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_ANON);
@@ -517,7 +517,7 @@ jerry_parse_function (const jerry_char_t *resource_name_p, /**< resource name (u
517517
JERRY_CONTEXT (resource_name) = ecma_find_or_create_literal_string (resource_name_p,
518518
(lit_utf8_size_t) resource_name_length);
519519
}
520-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
520+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
521521

522522
if (arg_list_p == NULL)
523523
{
@@ -3546,15 +3546,15 @@ jerry_get_backtrace (uint32_t max_depth) /**< depth limit of the backtrace */
35463546
jerry_value_t
35473547
jerry_get_resource_name (const jerry_value_t value) /**< jerry api value */
35483548
{
3549-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
3549+
#if ENABLED (JERRY_RESOURCE_NAME)
35503550
if (ecma_is_value_undefined (value))
35513551
{
35523552
if (JERRY_CONTEXT (vm_top_context_p) != NULL)
35533553
{
35543554
return ecma_copy_value (JERRY_CONTEXT (vm_top_context_p)->resource_name);
35553555
}
35563556
}
3557-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3557+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
35583558
#if ENABLED (JERRY_LINE_INFO)
35593559
else if (ecma_is_value_object (value))
35603560
{

jerry-core/config.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -684,4 +684,13 @@
684684
# define JERRY_ES2015_BUILTIN_CONTAINER 0
685685
#endif
686686

687+
/**
688+
* Resource name relatey types into a single guard
689+
*/
690+
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
691+
# define JERRY_RESOURCE_NAME 1
692+
#else
693+
# define JERRY_RESOURCE_NAME 0
694+
#endif
695+
687696
#endif /* !JERRYSCRIPT_CONFIG_H */

jerry-core/ecma/base/ecma-helpers.c

Lines changed: 45 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1441,17 +1441,7 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
14411441
#if ENABLED (JERRY_ES2015)
14421442
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
14431443
{
1444-
ecma_length_t formal_params_number = ecma_compiled_code_get_formal_params (bytecode_p);
1445-
1446-
uint8_t *byte_p = (uint8_t *) bytecode_p;
1447-
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
1448-
1449-
ecma_value_t *tagged_base_p = (ecma_value_t *) byte_p;
1450-
tagged_base_p -= formal_params_number;
1451-
1452-
ecma_collection_t *coll_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, tagged_base_p[-1]);
1453-
1454-
ecma_collection_destroy (coll_p);
1444+
ecma_collection_destroy (ecma_compiled_code_get_tagged_template_collection (bytecode_p));
14551445
}
14561446
#endif /* ENABLED (JERRY_ES2015) */
14571447

@@ -1484,17 +1474,17 @@ ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *b
14841474
JERRY_ASSERT (bytecode_header_p != NULL);
14851475
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS);
14861476

1487-
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
1488-
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
1477+
ecma_value_t *base_p = ecma_compiled_code_resolve_function_name (bytecode_header_p);
14891478

1490-
ecma_value_t *tagged_base_p = (ecma_value_t *) byte_p;
1491-
tagged_base_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
1479+
#if ENABLED (JERRY_RESOURCE_NAME)
1480+
base_p--;
1481+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
14921482

1493-
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, tagged_base_p[-1]);
1483+
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[-1]);
14941484
} /* ecma_compiled_code_get_tagged_template_collection */
14951485
#endif /* ENABLED (JERRY_ES2015) */
14961486

1497-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015)
1487+
#if ENABLED (JERRY_RESOURCE_NAME) || ENABLED (JERRY_ES2015)
14981488
/**
14991489
* Get the number of formal parameters of the compiled code
15001490
*
@@ -1515,7 +1505,44 @@ ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_heade
15151505

15161506
return ((cbc_uint8_arguments_t *) bytecode_header_p)->argument_end;
15171507
} /* ecma_compiled_code_get_formal_params */
1518-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
1508+
1509+
/**
1510+
* Resolve the position of the arguments list start of the compiled code
1511+
*
1512+
* @return start position of the arguments list start of the compiled code
1513+
*/
1514+
ecma_value_t *
1515+
ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p)
1516+
{
1517+
JERRY_ASSERT (bytecode_header_p != NULL);
1518+
1519+
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
1520+
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
1521+
1522+
return ((ecma_value_t *) byte_p) - ecma_compiled_code_get_formal_params (bytecode_header_p);
1523+
} /* ecma_compiled_code_resolve_arguments_start */
1524+
1525+
/**
1526+
* Resolve the position of the function name of the compiled code
1527+
*
1528+
* @return position of the function name of the compiled code
1529+
*/
1530+
inline ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
1531+
ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p)
1532+
{
1533+
JERRY_ASSERT (bytecode_header_p != NULL);
1534+
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
1535+
1536+
#if ENABLED (JERRY_ES2015)
1537+
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
1538+
{
1539+
base_p--;
1540+
}
1541+
#endif /* ENABLED (JERRY_ES2015) */
1542+
1543+
return base_p;
1544+
} /* ecma_compiled_code_resolve_function_name */
1545+
#endif /* ENABLED (JERRY_RESOURCE_NAME) || ENABLED (JERRY_ES2015) */
15191546

15201547
#if (JERRY_STACK_LIMIT != 0)
15211548
/**

jerry-core/ecma/base/ecma-helpers.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -488,9 +488,11 @@ void ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p);
488488
#if ENABLED (JERRY_ES2015)
489489
ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *bytecode_header_p);
490490
#endif /* ENABLED (JERRY_ES2015) */
491-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015)
491+
#if ENABLED (JERRY_RESOURCE_NAME) || ENABLED (JERRY_ES2015)
492492
ecma_length_t ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_p);
493-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
493+
ecma_value_t *ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p);
494+
ecma_value_t *ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p);
495+
#endif /* ENABLED (JERRY_RESOURCE_NAME) || ENABLED (JERRY_ES2015) */
494496
#if (JERRY_STACK_LIMIT != 0)
495497
uintptr_t ecma_get_current_stack_usage (void);
496498
#endif /* (JERRY_STACK_LIMIT != 0) */

jerry-core/ecma/base/ecma-literal-storage.c

Lines changed: 59 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -329,7 +329,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
329329
ecma_collection_t *lit_pool_p) /**< list of known values */
330330
{
331331
ecma_value_t *literal_p;
332-
uint32_t argument_end = 0;
332+
uint32_t argument_end;
333333
uint32_t register_end;
334334
uint32_t const_literal_end;
335335
uint32_t literal_end;
@@ -345,11 +345,7 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
345345
register_end = args_p->register_end;
346346
const_literal_end = args_p->const_literal_end - register_end;
347347
literal_end = args_p->literal_end - register_end;
348-
349-
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
350-
{
351-
argument_end = args_p->argument_end;
352-
}
348+
argument_end = args_p->argument_end;
353349
}
354350
else
355351
{
@@ -360,16 +356,15 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
360356
register_end = args_p->register_end;
361357
const_literal_end = args_p->const_literal_end - register_end;
362358
literal_end = args_p->literal_end - register_end;
363-
364-
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
365-
{
366-
argument_end = args_p->argument_end;
367-
}
359+
argument_end = args_p->argument_end;
368360
}
369361

370-
for (uint32_t i = 0; i < argument_end; i++)
362+
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
371363
{
372-
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
364+
for (uint32_t i = 0; i < argument_end; i++)
365+
{
366+
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
367+
}
373368
}
374369

375370
for (uint32_t i = 0; i < const_literal_end; i++)
@@ -389,16 +384,13 @@ ecma_save_literals_add_compiled_code (const ecma_compiled_code_t *compiled_code_
389384
}
390385
}
391386

392-
if (argument_end != 0)
393-
{
394-
uint8_t *byte_p = (uint8_t *) compiled_code_p;
395-
byte_p += ((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG;
396-
literal_p = ((ecma_value_t *) byte_p) - argument_end;
387+
uint8_t *byte_p = ((uint8_t *) compiled_code_p) + (((size_t) compiled_code_p->size) << JMEM_ALIGNMENT_LOG);
388+
literal_p = ecma_snapshot_resolve_serializable_values ((ecma_compiled_code_t *) compiled_code_p, byte_p);
397389

398-
for (uint32_t i = 0; i < argument_end; i++)
399-
{
400-
ecma_save_literals_append_value (literal_p[i], lit_pool_p);
401-
}
390+
while (literal_p < (ecma_value_t *) byte_p)
391+
{
392+
ecma_save_literals_append_value (*literal_p, lit_pool_p);
393+
literal_p++;
402394
}
403395
} /* ecma_save_literals_add_compiled_code */
404396

@@ -546,6 +538,51 @@ ecma_snapshot_get_literal (const uint8_t *literal_base_p, /**< literal start */
546538
return ecma_find_or_create_literal_string (literal_p + sizeof (uint16_t), length);
547539
} /* ecma_snapshot_get_literal */
548540

541+
/**
542+
* Compute the start of the serializable ecma-values of the bytecode
543+
* Related values:
544+
* - function argument names, if CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED is present
545+
* - function name, if CBC_CODE_FLAGS_CLASS_CONSTRUCTOR is not present and ES2015 profile is enabled
546+
* - resource name, if JERRY_RESOURCE_NAME is enabled
547+
*
548+
* @return pointer to the beginning of the serializable ecma-values
549+
*/
550+
ecma_value_t *
551+
ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p, /**< compiled code */
552+
uint8_t *bytecode_end_p) /**< end of the bytecode */
553+
{
554+
ecma_value_t *base_p = (ecma_value_t *) bytecode_end_p;
555+
556+
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_MAPPED_ARGUMENTS_NEEDED)
557+
{
558+
uint32_t argument_end;
559+
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
560+
{
561+
argument_end = ((cbc_uint16_arguments_t *) compiled_code_p)->argument_end;
562+
}
563+
else
564+
{
565+
argument_end = ((cbc_uint8_arguments_t *) compiled_code_p)->argument_end;
566+
}
567+
568+
base_p -= argument_end;
569+
}
570+
571+
#if ENABLED (JERRY_ES2015)
572+
/* function name */
573+
if (!(compiled_code_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
574+
{
575+
base_p--;
576+
}
577+
#endif /* ENABLED (JERRY_ES2015) */
578+
579+
#if ENABLED (JERRY_RESOURCE_NAME)
580+
/* resource name */
581+
base_p--;
582+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
583+
584+
return base_p;
585+
} /* ecma_snapshot_resolve_serializable_values */
549586
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE) */
550587

551588
/**

jerry-core/ecma/base/ecma-literal-storage.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@ bool ecma_save_literals_for_snapshot (ecma_collection_t *lit_pool_p, uint32_t *b
5555
#if ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE)
5656
ecma_value_t
5757
ecma_snapshot_get_literal (const uint8_t *literal_base_p, ecma_value_t literal_value);
58+
ecma_value_t *
59+
ecma_snapshot_resolve_serializable_values (ecma_compiled_code_t *compiled_code_p, uint8_t *byte_code_end_p);
5860
#endif /* ENABLED (JERRY_SNAPSHOT_EXEC) || ENABLED (JERRY_SNAPSHOT_SAVE) */
5961

6062
/**

jerry-core/ecma/builtin-objects/ecma-builtin-function-prototype.c

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -297,6 +297,11 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
297297
}
298298

299299
#if ENABLED (JERRY_ES2015)
300+
if (prototype_obj_p != NULL)
301+
{
302+
ecma_deref_object (prototype_obj_p);
303+
}
304+
300305
ecma_integer_value_t len = 0;
301306
ecma_string_t *len_string = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH);
302307
ecma_property_descriptor_t prop_desc;
@@ -307,6 +312,7 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
307312
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY)
308313
if (ECMA_IS_VALUE_ERROR (status))
309314
{
315+
ecma_deref_object (function_p);
310316
return status;
311317
}
312318
#endif /* ENABLED (JERRY_ES2015_BUILTIN_PROXY) */
@@ -319,6 +325,7 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
319325

320326
if (ECMA_IS_VALUE_ERROR (len_value))
321327
{
328+
ecma_deref_object (function_p);
322329
return len_value;
323330
}
324331

@@ -328,14 +335,36 @@ ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**
328335
ecma_op_to_integer (len_value, &len_num);
329336
len = (ecma_integer_value_t) len_num;
330337
}
338+
ecma_free_value (len_value);
331339
}
332340

333341
bound_func_p->target_length = len;
334342

335-
if (prototype_obj_p != NULL)
343+
/* 12. */
344+
ecma_value_t name_value = ecma_op_object_get_by_magic_id (this_arg_obj_p, LIT_MAGIC_STRING_NAME);
345+
if (ECMA_IS_VALUE_ERROR (name_value))
336346
{
337-
ecma_deref_object (prototype_obj_p);
347+
ecma_deref_object (function_p);
348+
return name_value;
338349
}
350+
351+
if (!ecma_is_value_string (name_value))
352+
{
353+
ecma_free_value (name_value);
354+
name_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY);
355+
}
356+
357+
ecma_value_t bound_function_name = ecma_op_function_form_name (name_value, "bound ", 6);
358+
359+
ecma_free_value (name_value);
360+
361+
ecma_property_value_t *name_prop_value_p;
362+
name_prop_value_p = ecma_create_named_data_property (function_p,
363+
ecma_get_magic_string (LIT_MAGIC_STRING_NAME),
364+
ECMA_PROPERTY_FLAG_CONFIGURABLE,
365+
NULL);
366+
367+
name_prop_value_p->value = bound_function_name;
339368
#endif /* ENABLED (JERRY_ES2015) */
340369

341370
/*

jerry-core/ecma/builtin-objects/ecma-builtin-function.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
#include "js-parser.h"
2525
#include "lit-magic-strings.h"
2626

27-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM)
27+
#if ENABLED (JERRY_RESOURCE_NAME)
2828
#include "jcontext.h"
29-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
29+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
3030

3131
#define ECMA_BUILTINS_INTERNAL
3232
#include "ecma-builtins-internal.h"

jerry-core/ecma/operations/ecma-eval.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -93,9 +93,9 @@ ecma_op_eval_chars_buffer (const lit_utf8_byte_t *code_p, /**< code characters b
9393

9494
parse_opts |= ECMA_PARSE_EVAL;
9595

96-
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES)
96+
#if ENABLED (JERRY_RESOURCE_NAME)
9797
JERRY_CONTEXT (resource_name) = ecma_make_magic_string_value (LIT_MAGIC_STRING_RESOURCE_EVAL);
98-
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ERROR_MESSAGES) */
98+
#endif /* ENABLED (JERRY_RESOURCE_NAME) */
9999

100100
#if ENABLED (JERRY_ES2015)
101101
ECMA_CLEAR_LOCAL_PARSE_OPTS ();

0 commit comments

Comments
 (0)