Skip to content

Commit 9900717

Browse files
committed
Implement ES2015 class feature (part II.)
This patch is the second milestone of the implementation of this new language element. Partly supported: - Single inheritance The following features are going to be implemeted in an other patch: - Implicit constructor in class heritage - Specific behaviour while extending with the built-in 'Array' object JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik [email protected]
1 parent 8789784 commit 9900717

27 files changed

+871
-84
lines changed

jerry-core/config.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@
3737
*/
3838
#ifdef CONFIG_DISABLE_ES2015
3939
# define CONFIG_DISABLE_ES2015_ARROW_FUNCTION
40-
# define CONFIG_DISABLE_ES2015_CLASS
4140
# define CONFIG_DISABLE_ES2015_BUILTIN
41+
# define CONFIG_DISABLE_ES2015_CLASS
4242
# define CONFIG_DISABLE_ES2015_PROMISE_BUILTIN
4343
# define CONFIG_DISABLE_ES2015_TEMPLATE_STRINGS
4444
# define CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN

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

Lines changed: 21 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,11 @@ typedef enum
8888
{
8989
ECMA_PARSE_NO_OPTS = 0, /**< no options passed */
9090
ECMA_PARSE_STRICT_MODE = (1 << 0), /**< enable strict mode */
91-
ECMA_PARSE_DIRECT_EVAL = (1 << 1) /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
91+
ECMA_PARSE_DIRECT_EVAL = (1 << 1), /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */
92+
ECMA_PARSE_EVAL_SUPER = (1 << 2), /**< the current context has super reference */
93+
ECMA_PARSE_EVAL_CONSTRUCTOR_SUPER = (1 << 3), /**< the current context is a class constructor */
94+
ECMA_PARSE_EVAL_SUPER_ARROW = (1 << 4), /**< the current context is an arrow function */
95+
ECMA_PARSE_EVAL_STATIC_SUPER = (1 << 5) /**< the current context is a static class method */
9296
} ecma_parse_opts_t;
9397

9498
/**
@@ -626,12 +630,27 @@ typedef enum
626630
ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE = 13, /**< declarative lexical environment */
627631
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND = 14, /**< object-bound lexical environment
628632
* with provideThis flag */
633+
ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND = 15, /**< object-bound lexical environment
634+
* with provided super reference */
629635

630636
ECMA_LEXICAL_ENVIRONMENT_TYPE_START = ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE, /**< first lexical
631637
* environment type */
632-
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND /**< maximum value */
638+
ECMA_LEXICAL_ENVIRONMENT_TYPE__MAX = ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND /**< maximum value */
633639
} ecma_lexical_environment_type_t;
634640

641+
/**
642+
* Option flags for super call.
643+
*/
644+
typedef enum
645+
{
646+
ECMA_SUPER_CALL_NO_OPTS = 0, /**< no speficied options are provided */
647+
ECMA_SUPER_CALL_CONSTRUCTOR = (1 << 0), /**< the current call is a super constructor call */
648+
ECMA_SUPER_CALL_INITIALIZED = (1 << 1), /**< 'this' and 'super' are accessible in the current context */
649+
ECMA_SUPER_CALL_INSTANTIATED = (1 << 2), /**< set the this_binding value after resolving the
650+
* super property referece */
651+
ECMA_SUPER_CALL_STATIC_SUPER = (1 << 3), /**< the current function is a static class method */
652+
} ecma_super_call_opts_t;
653+
635654
/**
636655
* Ecma object type mask for getting the object type.
637656
*/

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

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -140,16 +140,15 @@ ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p) /**< outer
140140
*/
141141
ecma_object_t *
142142
ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, /**< outer lexical environment */
143-
ecma_object_t *binding_obj_p) /**< binding object */
143+
ecma_object_t *binding_obj_p, /**< binding object */
144+
ecma_lexical_environment_type_t type) /**< type of the new lexical environment */
144145
{
145146
JERRY_ASSERT (binding_obj_p != NULL
146147
&& !ecma_is_lexical_environment (binding_obj_p));
147148

148149
ecma_object_t *new_lexical_environment_p = ecma_alloc_object ();
149150

150-
uint16_t type = ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND;
151-
152-
new_lexical_environment_p->type_flags_refs = type;
151+
new_lexical_environment_p->type_flags_refs = (uint16_t) (ECMA_OBJECT_FLAG_BUILT_IN_OR_LEXICAL_ENV | type);
153152

154153
ecma_init_gc_info (new_lexical_environment_p);
155154

@@ -358,7 +357,7 @@ ecma_get_lex_env_binding_object (const ecma_object_t *object_p) /**< object-boun
358357
{
359358
JERRY_ASSERT (object_p != NULL);
360359
JERRY_ASSERT (ecma_is_lexical_environment (object_p));
361-
JERRY_ASSERT (ecma_get_lex_env_type (object_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
360+
JERRY_ASSERT (ecma_get_lex_env_type (object_p) != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
362361

363362
return ECMA_GET_NON_NULL_POINTER (ecma_object_t,
364363
object_p->property_list_or_bound_object_cp);

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,9 @@ ecma_collection_iterator_next (ecma_value_t *iterator_p);
297297
/* ecma-helpers.c */
298298
ecma_object_t *ecma_create_object (ecma_object_t *prototype_object_p, size_t ext_object_size, ecma_object_type_t type);
299299
ecma_object_t *ecma_create_decl_lex_env (ecma_object_t *outer_lexical_environment_p);
300-
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p, ecma_object_t *binding_obj_p);
300+
ecma_object_t *ecma_create_object_lex_env (ecma_object_t *outer_lexical_environment_p,
301+
ecma_object_t *binding_obj_p,
302+
ecma_lexical_environment_type_t type);
301303
bool JERRY_ATTR_PURE ecma_is_lexical_environment (const ecma_object_t *object_p);
302304
bool JERRY_ATTR_PURE ecma_get_object_extensible (const ecma_object_t *object_p);
303305
void ecma_set_object_extensible (ecma_object_t *object_p, bool is_extensible);

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

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@
2929
#include "vm.h"
3030
#include "jrt-libc-includes.h"
3131
#include "jrt-bit-fields.h"
32+
#ifndef CONFIG_DISABLE_ES2015_CLASS
33+
#include "jcontext.h"
34+
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
3235

3336
#define ECMA_BUILTINS_INTERNAL
3437
#include "ecma-builtins-internal.h"
@@ -72,6 +75,27 @@ ecma_builtin_global_object_eval (ecma_value_t this_arg, /**< this argument */
7275
parse_opts |= ECMA_PARSE_STRICT_MODE;
7376
}
7477

78+
#ifndef CONFIG_DISABLE_ES2015_CLASS
79+
uint32_t super_call_opts = JERRY_CONTEXT (vm_top_context_p)->super_call_opts;
80+
81+
if (super_call_opts & ECMA_PARSE_EVAL_CONSTRUCTOR_SUPER)
82+
{
83+
parse_opts |= ECMA_PARSE_EVAL_CONSTRUCTOR_SUPER;
84+
}
85+
if (super_call_opts & ECMA_PARSE_EVAL_SUPER)
86+
{
87+
parse_opts |= ECMA_PARSE_EVAL_SUPER;
88+
}
89+
if (super_call_opts & ECMA_PARSE_EVAL_SUPER_ARROW)
90+
{
91+
parse_opts |= ECMA_PARSE_EVAL_SUPER_ARROW;
92+
}
93+
if (super_call_opts & ECMA_PARSE_EVAL_STATIC_SUPER)
94+
{
95+
parse_opts |= ECMA_PARSE_EVAL_STATIC_SUPER;
96+
}
97+
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
98+
7599
if (!ecma_is_value_string (x))
76100
{
77101
/* step 1 */

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,10 @@ ecma_value_t
4343
ecma_op_create_array_object (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len,
4444
bool is_treat_single_arg_as_length);
4545

46+
ecma_value_t
47+
ecma_op_create_array_object_by_constructor (const ecma_value_t *arguments_list_p, ecma_length_t arguments_list_len,
48+
bool is_treat_single_arg_as_length, ecma_object_t *object_p);
49+
4650
ecma_value_t
4751
ecma_op_array_object_set_length (ecma_object_t *object_p, ecma_value_t new_value, uint32_t flags);
4852

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

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -403,19 +403,12 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
403403
} /* ecma_op_function_has_instance */
404404

405405

406-
#ifndef CONFIG_DISABLE_ES2015_CLASS
407-
/**
408-
* Indicates whether the class has been invoked with 'new'.
409-
*/
410-
#define ECMA_CLASS_CONSTRUCT_FLAG ((uintptr_t) 0x01u)
411-
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
412-
413406
/**
414407
* Sets the construct flag in the arguments list pointer.
415408
*
416409
* @return arguments list pointer with the construct flag
417410
*/
418-
static inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
411+
inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
419412
ecma_op_function_set_construct_flag (const ecma_value_t *arguments_list_p) /**< original arguments list pointer */
420413
{
421414
/* Any ecma value list must be aligned to 4 byte. */
@@ -433,7 +426,7 @@ ecma_op_function_set_construct_flag (const ecma_value_t *arguments_list_p) /**<
433426
*
434427
* @return arguments list pointer without the construct flag
435428
*/
436-
static inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
429+
inline const ecma_value_t * JERRY_ATTR_ALWAYS_INLINE
437430
ecma_op_function_clear_construct_flag (const ecma_value_t *arguments_list_p) /**< modified arguments list pointer */
438431
{
439432
#ifndef CONFIG_DISABLE_ES2015_CLASS

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

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,13 @@
1919
#include "ecma-globals.h"
2020
#include "vm.h"
2121

22+
#ifndef CONFIG_DISABLE_ES2015_CLASS
23+
/**
24+
* Indicates whether the class has been invoked with 'new'.
25+
*/
26+
#define ECMA_CLASS_CONSTRUCT_FLAG ((uintptr_t) 0x01u)
27+
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
28+
2229
/** \addtogroup ecma ECMA
2330
* @{
2431
*
@@ -51,6 +58,12 @@ const ecma_compiled_code_t *
5158
ecma_op_arrow_function_get_compiled_code (ecma_arrow_function_t *arrow_function_p);
5259
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
5360

61+
const ecma_value_t *
62+
ecma_op_function_set_construct_flag (const ecma_value_t *arguments_list_p);
63+
64+
const ecma_value_t *
65+
ecma_op_function_clear_construct_flag (const ecma_value_t *arguments_list_p);
66+
5467
ecma_value_t
5568
ecma_op_function_has_instance (ecma_object_t *func_obj_p, ecma_value_t value);
5669

jerry-core/ecma/operations/ecma-lex-env.c

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,9 @@ ecma_init_global_lex_env (void)
4141
{
4242
ecma_object_t *glob_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL);
4343

44-
JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL, glob_obj_p);
44+
JERRY_CONTEXT (ecma_global_lex_env_p) = ecma_create_object_lex_env (NULL,
45+
glob_obj_p,
46+
ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
4547

4648
ecma_deref_object (glob_obj_p);
4749
} /* ecma_init_global_lex_env */
@@ -86,15 +88,21 @@ ecma_op_has_binding (ecma_object_t *lex_env_p, /**< lexical environment */
8688
JERRY_ASSERT (lex_env_p != NULL
8789
&& ecma_is_lexical_environment (lex_env_p));
8890

89-
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
91+
ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
92+
93+
if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
9094
{
9195
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
9296

9397
return (property_p != NULL);
9498
}
9599
else
96100
{
97-
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
101+
#ifndef CONFIG_DISABLE_ES2015_CLASS
102+
JERRY_ASSERT (lex_env_type != ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE);
103+
#else /* CONFIG_DISABLE_ES2015_CLASS */
104+
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
105+
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
98106

99107
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
100108

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

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,30 @@ ecma_op_resolve_reference_base (ecma_object_t *lex_env_p, /**< starting lexical
5959
return NULL;
6060
} /* ecma_op_resolve_reference_base */
6161

62+
63+
/**
64+
* Resolve super reference.
65+
*
66+
* @return value of the reference
67+
*/
68+
ecma_value_t
69+
ecma_op_resolve_super_reference_value (ecma_object_t *lex_env_p) /**< starting lexical environment */
70+
{
71+
JERRY_ASSERT (lex_env_p != NULL);
72+
73+
while (lex_env_p != NULL)
74+
{
75+
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND)
76+
{
77+
return ecma_make_object_value (ecma_get_lex_env_binding_object (lex_env_p));
78+
}
79+
80+
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
81+
}
82+
83+
return ECMA_VALUE_UNDEFINED;
84+
} /* ecma_op_resolve_super_reference_value */
85+
6286
/**
6387
* Resolve value corresponding to reference.
6488
*
@@ -69,10 +93,11 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
6993
ecma_string_t *name_p) /**< identifier's name */
7094
{
7195
JERRY_ASSERT (lex_env_p != NULL);
72-
7396
while (lex_env_p != NULL)
7497
{
75-
if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
98+
ecma_lexical_environment_type_t lex_env_type = ecma_get_lex_env_type (lex_env_p);
99+
100+
if (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE)
76101
{
77102
ecma_property_t *property_p = ecma_find_named_property (lex_env_p, name_p);
78103

@@ -81,9 +106,16 @@ ecma_op_resolve_reference_value (ecma_object_t *lex_env_p, /**< starting lexical
81106
return ecma_fast_copy_value (ECMA_PROPERTY_VALUE_PTR (property_p)->value);
82107
}
83108
}
109+
#ifndef CONFIG_DISABLE_ES2015_CLASS
110+
else if (JERRY_UNLIKELY (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_SUPER_OBJECT_BOUND))
111+
{
112+
lex_env_p = ecma_get_lex_env_outer_reference (lex_env_p);
113+
continue;
114+
}
115+
#endif /* !CONFIG_DISABLE_ES2015_CLASS */
84116
else
85117
{
86-
JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
118+
JERRY_ASSERT (lex_env_type == ECMA_LEXICAL_ENVIRONMENT_THIS_OBJECT_BOUND);
87119

88120
ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p);
89121

0 commit comments

Comments
 (0)