Skip to content

Commit 5da2db4

Browse files
committed
Implement function.name
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent 95aa827 commit 5da2db4

19 files changed

+692
-75
lines changed

jerry-core/api/jerry-snapshot.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -761,6 +761,13 @@ jerry_generate_snapshot_with_args (const jerry_char_t *resource_name_p, /**< scr
761761
globals.regex_found = false;
762762
globals.class_found = false;
763763

764+
uint32_t status_flags = ECMA_PARSE_SNAPSHOT;
765+
766+
if (generate_snapshot_opts & JERRY_SNAPSHOT_SAVE_STRICT)
767+
{
768+
status_flags |= ECMA_PARSE_STRICT_MODE;
769+
}
770+
764771
parse_status = parser_parse_script (args_p,
765772
args_size,
766773
source_p,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,7 @@ typedef enum
128128
*/
129129
ECMA_PARSE_INTERNAL_FOR_IN_OFF_CONTEXT_ERROR = (1u << 9),
130130
#endif /* !JERRY_NDEBUG */
131+
ECMA_PARSE_SNAPSHOT = (1u << 10), /**< script parsing is called by the snapshot tool */
131132
} ecma_parse_opts_t;
132133

133134
/**
@@ -206,6 +207,7 @@ enum
206207
ECMA_VALUE_UNINITIALIZED = ECMA_MAKE_VALUE (10), /**< a special value for uninitialized let/const declarations */
207208
ECMA_VALUE_SPREAD_ELEMENT = ECMA_MAKE_VALUE (11), /**< a special value for spread elements in array initialization
208209
* or function call argument list */
210+
ECMA_VALUE_ANONYMOUS = ECMA_MAKE_VALUE (12), /**< represents anonymous function declaration */
209211
};
210212

211213
#if !ENABLED (JERRY_NUMBER_TYPE_FLOAT64)

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

Lines changed: 41 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1439,19 +1439,17 @@ ecma_bytecode_deref (ecma_compiled_code_t *bytecode_p) /**< byte code pointer */
14391439
#endif /* ENABLED (JERRY_DEBUGGER) */
14401440

14411441
#if ENABLED (JERRY_ES2015)
1442-
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
1443-
{
1444-
ecma_length_t formal_params_number = ecma_compiled_code_get_formal_params (bytecode_p);
14451442

1446-
uint8_t *byte_p = (uint8_t *) bytecode_p;
1447-
byte_p += ((size_t) bytecode_p->size) << JMEM_ALIGNMENT_LOG;
1443+
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_p);
14481444

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]);
1445+
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
1446+
{
1447+
ecma_free_value (*(--base_p));
1448+
}
14531449

1454-
ecma_collection_destroy (coll_p);
1450+
if (bytecode_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
1451+
{
1452+
ecma_collection_destroy (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, base_p[-1]));
14551453
}
14561454
#endif /* ENABLED (JERRY_ES2015) */
14571455

@@ -1484,11 +1482,12 @@ ecma_compiled_code_get_tagged_template_collection (const ecma_compiled_code_t *b
14841482
JERRY_ASSERT (bytecode_header_p != NULL);
14851483
JERRY_ASSERT (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS);
14861484

1487-
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
1488-
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
1485+
ecma_value_t *tagged_base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
14891486

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);
1487+
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
1488+
{
1489+
tagged_base_p--;
1490+
}
14921491

14931492
return ECMA_GET_INTERNAL_VALUE_POINTER (ecma_collection_t, tagged_base_p[-1]);
14941493
} /* ecma_compiled_code_get_tagged_template_collection */
@@ -1515,6 +1514,34 @@ ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_heade
15151514

15161515
return ((cbc_uint8_arguments_t *) bytecode_header_p)->argument_end;
15171516
} /* ecma_compiled_code_get_formal_params */
1517+
1518+
/**
1519+
* Resolve the position of the arguments list start of the compiled code
1520+
*
1521+
* @return start position of the arguments list start of the compiled code
1522+
*/
1523+
ecma_value_t *
1524+
ecma_compiled_code_resolve_arguments_start (const ecma_compiled_code_t *bytecode_header_p)
1525+
{
1526+
JERRY_ASSERT (bytecode_header_p != NULL);
1527+
1528+
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
1529+
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
1530+
1531+
return ((ecma_value_t *) byte_p) - ecma_compiled_code_get_formal_params (bytecode_header_p);
1532+
} /* ecma_compiled_code_resolve_arguments_start */
1533+
1534+
/**
1535+
* Resolve the position of the function name of the compiled code
1536+
*
1537+
* @return position of the function name of the compiled code
1538+
*/
1539+
inline ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
1540+
ecma_compiled_code_resolve_function_name (const ecma_compiled_code_t *bytecode_header_p)
1541+
{
1542+
JERRY_ASSERT (bytecode_header_p != NULL);
1543+
return ecma_compiled_code_resolve_arguments_start (bytecode_header_p) - 1;
1544+
} /* ecma_compiled_code_resolve_function_name */
15181545
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
15191546

15201547
#if (JERRY_STACK_LIMIT != 0)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,8 @@ ecma_collection_t *ecma_compiled_code_get_tagged_template_collection (const ecma
490490
#endif /* ENABLED (JERRY_ES2015) */
491491
#if ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015)
492492
ecma_length_t ecma_compiled_code_get_formal_params (const ecma_compiled_code_t *bytecode_p);
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);
493495
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) || ENABLED (JERRY_ES2015) */
494496
#if (JERRY_STACK_LIMIT != 0)
495497
uintptr_t ecma_get_current_stack_usage (void);

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

Lines changed: 30 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,35 @@ 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+
ecma_stringbuilder_t builder = ecma_stringbuilder_create_raw ((const lit_utf8_byte_t *) "bound ", 6);
352+
353+
if (ecma_is_value_string (name_value))
354+
{
355+
ecma_stringbuilder_append (&builder, ecma_get_string_from_value (name_value));
356+
}
357+
358+
ecma_free_value (name_value);
359+
360+
ecma_property_value_t *name_prop_value_p;
361+
name_prop_value_p = ecma_create_named_data_property (function_p,
362+
ecma_get_magic_string (LIT_MAGIC_STRING_NAME),
363+
ECMA_PROPERTY_FLAG_CONFIGURABLE,
364+
NULL);
365+
366+
name_prop_value_p->value = ecma_make_string_value (ecma_stringbuilder_finalize (&builder));
339367
#endif /* ENABLED (JERRY_ES2015) */
340368

341369
/*

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

Lines changed: 96 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
#include "ecma-objects-general.h"
2626
#include "ecma-objects-arguments.h"
2727
#include "ecma-proxy-object.h"
28+
#include "ecma-symbol-object.h"
2829
#include "ecma-try-catch-macro.h"
2930
#include "jcontext.h"
3031

@@ -46,23 +47,77 @@ ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p)
4647
{
4748
JERRY_ASSERT (bytecode_header_p != NULL);
4849

49-
uint8_t *byte_p = (uint8_t *) bytecode_header_p;
50-
byte_p += ((size_t) bytecode_header_p->size) << JMEM_ALIGNMENT_LOG;
51-
52-
ecma_value_t *resource_name_p = (ecma_value_t *) byte_p;
53-
resource_name_p -= ecma_compiled_code_get_formal_params (bytecode_header_p);
50+
ecma_value_t *base_p = ecma_compiled_code_resolve_arguments_start (bytecode_header_p);
5451

5552
#if ENABLED (JERRY_ES2015)
5653
if (bytecode_header_p->status_flags & CBC_CODE_FLAG_HAS_TAGGED_LITERALS)
5754
{
58-
resource_name_p--;
55+
base_p--;
56+
}
57+
58+
if (!(bytecode_header_p->status_flags & CBC_CODE_FLAGS_CLASS_CONSTRUCTOR))
59+
{
60+
base_p--;
5961
}
6062
#endif /* ENABLED (JERRY_ES2015) */
6163

62-
return resource_name_p[-1];
64+
return base_p[-1];
6365
} /* ecma_op_resource_name */
6466
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
6567

68+
#if ENABLED (JERRY_ES2015)
69+
/**
70+
* SetFunctionName operation
71+
*
72+
* See also: ECMAScript v6, 9.2.1.1
73+
*
74+
* @return resource name as ecma-string
75+
*/
76+
ecma_value_t
77+
ecma_op_function_form_name (ecma_value_t prop_name, /**< property name */
78+
char *prefix_p, /**< prefix */
79+
lit_utf8_size_t prefix_size) /**< prefix length */
80+
{
81+
ecma_string_t *prop_name_p = ecma_get_prop_name_from_value (prop_name);
82+
83+
/* 4. */
84+
if (ecma_prop_name_is_symbol (prop_name_p))
85+
{
86+
/* .a */
87+
ecma_string_t *string_desc_p = ecma_get_symbol_description (prop_name_p);
88+
89+
/* .b */
90+
if (ecma_string_is_empty (string_desc_p))
91+
{
92+
prop_name_p = string_desc_p;
93+
}
94+
/* .c */
95+
else
96+
{
97+
ecma_stringbuilder_t builder = ecma_stringbuilder_create_raw ((lit_utf8_byte_t *) "[", 1);
98+
ecma_stringbuilder_append (&builder, string_desc_p);
99+
ecma_stringbuilder_append_byte (&builder, (lit_utf8_byte_t) LIT_CHAR_RIGHT_SQUARE);
100+
prop_name_p = ecma_stringbuilder_finalize (&builder);
101+
}
102+
}
103+
else
104+
{
105+
ecma_ref_ecma_string (prop_name_p);
106+
}
107+
108+
/* 5. */
109+
if (JERRY_UNLIKELY (prefix_p != NULL))
110+
{
111+
ecma_stringbuilder_t builder = ecma_stringbuilder_create_raw ((lit_utf8_byte_t *) prefix_p, prefix_size);
112+
ecma_stringbuilder_append (&builder, prop_name_p);
113+
ecma_deref_ecma_string (prop_name_p);
114+
prop_name_p = ecma_stringbuilder_finalize (&builder);
115+
}
116+
117+
return ecma_make_string_value (prop_name_p);
118+
} /* ecma_op_function_form_name */
119+
#endif /* ENABLED (JERRY_ES2015) */
120+
66121
/**
67122
* IsCallable operation.
68123
*
@@ -345,6 +400,12 @@ ecma_op_create_dynamic_function (const ecma_value_t *arguments_list_p, /**< argu
345400
{
346401
JERRY_ASSERT (ecma_is_value_true (ret_value));
347402

403+
#if ENABLED (JERRY_ES2015)
404+
ecma_value_t *func_name_p;
405+
func_name_p = ecma_compiled_code_resolve_function_name ((const ecma_compiled_code_t *) bytecode_data_p);
406+
*func_name_p = ecma_make_magic_string_value (LIT_MAGIC_STRING_ANONYMOUS);
407+
#endif /* ENABLED (JERRY_ES2015) */
408+
348409
ecma_object_t *global_env_p = ecma_get_global_environment ();
349410
ecma_builtin_id_t fallback_proto = ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE;
350411

@@ -1417,6 +1478,34 @@ ecma_op_function_try_to_lazy_instantiate_property (ecma_object_t *object_p, /**<
14171478

14181479
return NULL;
14191480
}
1481+
1482+
if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_NAME))
1483+
{
1484+
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
1485+
if (!ECMA_GET_SECOND_BIT_FROM_POINTER_TAG (ext_func_p->u.function.scope_cp))
1486+
{
1487+
/* Set tag bit to represent initialized 'name' property */
1488+
ECMA_SET_SECOND_BIT_TO_POINTER_TAG (ext_func_p->u.function.scope_cp);
1489+
const ecma_compiled_code_t *bytecode_data_p = ecma_op_function_get_compiled_code (ext_func_p);
1490+
1491+
ecma_value_t value = *ecma_compiled_code_resolve_function_name (bytecode_data_p);
1492+
if (value != ECMA_VALUE_ANONYMOUS)
1493+
{
1494+
JERRY_ASSERT (ecma_is_value_string (value));
1495+
1496+
/* Initialize 'name' property */
1497+
ecma_property_t *value_prop_p;
1498+
ecma_property_value_t *value_p = ecma_create_named_data_property (object_p,
1499+
property_name_p,
1500+
ECMA_PROPERTY_FLAG_CONFIGURABLE,
1501+
&value_prop_p);
1502+
value_p->value = ecma_copy_value (value);
1503+
return value_prop_p;
1504+
}
1505+
}
1506+
1507+
return NULL;
1508+
}
14201509
#endif /* ENABLED (JERRY_ES2015) */
14211510

14221511
if (ecma_compare_ecma_string_to_magic_id (property_name_p, LIT_MAGIC_STRING_PROTOTYPE)

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@
3131
ecma_value_t ecma_op_resource_name (const ecma_compiled_code_t *bytecode_header_p);
3232
#endif /* ENABLED (JERRY_LINE_INFO) || ENABLED (JERRY_ES2015_MODULE_SYSTEM) */
3333

34+
#if ENABLED (JERRY_ES2015)
35+
ecma_value_t ecma_op_function_form_name (ecma_value_t prop_name, char *prefix_p, lit_utf8_size_t prefix_size);
36+
#endif /* ENABLED (JERRY_ES2015) */
37+
3438
bool ecma_op_is_callable (ecma_value_t value);
3539
bool ecma_op_object_is_callable (ecma_object_t *obj_p);
3640
bool ecma_is_constructor (ecma_value_t value);

jerry-core/lit/lit-magic-strings.inc.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -589,6 +589,9 @@ LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_TYPE_ERROR_UL, "TypeError")
589589
#endif
590590
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_UNDEFINED_UL, "Undefined")
591591
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING__PROTO__, "__proto__")
592+
#if ENABLED (JERRY_ES2015)
593+
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ANONYMOUS, "anonymous")
594+
#endif
592595
LIT_MAGIC_STRING_DEF (LIT_MAGIC_STRING_ARGUMENTS, "arguments")
593596
#if ENABLED (JERRY_ES2015_BUILTIN_PROXY) \
594597
|| ENABLED (JERRY_ES2015_BUILTIN_REFLECT)

jerry-core/lit/lit-magic-strings.ini

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,7 @@ LIT_MAGIC_STRING_UNESCAPE = "unescape"
232232
LIT_MAGIC_STRING_WRITABLE = "writable"
233233
LIT_MAGIC_STRING_NEGATIVE_INFINITY_UL = "-Infinity"
234234
LIT_MAGIC_STRING_ARGUMENTS_UL = "Arguments"
235+
LIT_MAGIC_STRING_ANONYMOUS = "anonymous"
235236
LIT_MAGIC_STRING_CONSTRUCT = "construct"
236237
LIT_MAGIC_STRING_EVAL_ERROR_UL = "EvalError"
237238
LIT_MAGIC_STRING_INT8_ARRAY_UL = "Int8Array"

0 commit comments

Comments
 (0)