Implement this binding for arrow functions.
JerryScript-DCO-1.0-Signed-off-by: Zoltan Herczeg zherczeg.u-szeged@partner.samsung.com
This commit is contained in:
@@ -131,14 +131,14 @@ ecma_alloc_extended_object (size_t size) /**< size of object */
|
|||||||
* Dealloc memory of an extended object
|
* Dealloc memory of an extended object
|
||||||
*/
|
*/
|
||||||
inline void __attr_always_inline___
|
inline void __attr_always_inline___
|
||||||
ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, /**< property pair to be freed */
|
ecma_dealloc_extended_object (ecma_object_t *object_p, /**< extended object */
|
||||||
size_t size) /**< size of object */
|
size_t size) /**< size of object */
|
||||||
{
|
{
|
||||||
#ifdef JMEM_STATS
|
#ifdef JMEM_STATS
|
||||||
jmem_stats_free_object_bytes (size);
|
jmem_stats_free_object_bytes (size);
|
||||||
#endif /* JMEM_STATS */
|
#endif /* JMEM_STATS */
|
||||||
|
|
||||||
jmem_heap_free_block (ext_object_p, size);
|
jmem_heap_free_block (object_p, size);
|
||||||
} /* ecma_dealloc_extended_object */
|
} /* ecma_dealloc_extended_object */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ ecma_extended_object_t *ecma_alloc_extended_object (size_t size);
|
|||||||
/**
|
/**
|
||||||
* Dealloc memory of an extended object
|
* Dealloc memory of an extended object
|
||||||
*/
|
*/
|
||||||
void ecma_dealloc_extended_object (ecma_extended_object_t *ext_object_p, size_t size);
|
void ecma_dealloc_extended_object (ecma_object_t *object_p, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate memory for ecma-number
|
* Allocate memory for ecma-number
|
||||||
|
|||||||
@@ -348,13 +348,26 @@ ecma_gc_mark (ecma_object_t *object_p) /**< object to mark from */
|
|||||||
{
|
{
|
||||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||||
|
|
||||||
ecma_object_t *scope_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
ecma_gc_set_object_visited (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_object_t,
|
||||||
ext_func_p->u.function.scope_cp);
|
ext_func_p->u.function.scope_cp));
|
||||||
|
|
||||||
ecma_gc_set_object_visited (scope_p);
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
case ECMA_OBJECT_TYPE_ARROW_FUNCTION:
|
||||||
|
{
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
|
||||||
|
|
||||||
|
ecma_gc_set_object_visited (ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||||
|
arrow_func_p->scope_cp));
|
||||||
|
|
||||||
|
if (ecma_is_value_object (arrow_func_p->this_binding))
|
||||||
|
{
|
||||||
|
ecma_gc_set_object_visited (ecma_get_object_from_value (arrow_func_p->this_binding));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
default:
|
default:
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
@@ -554,7 +567,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
{
|
{
|
||||||
ecma_length_t arraybuffer_length = ext_object_p->u.class_prop.u.length;
|
ecma_length_t arraybuffer_length = ext_object_p->u.class_prop.u.length;
|
||||||
size_t size = sizeof (ecma_extended_object_t) + arraybuffer_length;
|
size_t size = sizeof (ecma_extended_object_t) + arraybuffer_length;
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, size);
|
ecma_dealloc_extended_object (object_p, size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -565,7 +578,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value);
|
ecma_free_value_if_not_object (ext_object_p->u.class_prop.u.value);
|
||||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->fulfill_reactions, false);
|
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->fulfill_reactions, false);
|
||||||
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->reject_reactions, false);
|
ecma_free_values_collection (((ecma_promise_object_t *) object_p)->reject_reactions, false);
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, sizeof (ecma_promise_object_t));
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_promise_object_t));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
#endif /* !CONFIG_DISABLE_ES2015_PROMISE_BUILTIN */
|
||||||
@@ -576,7 +589,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, ext_object_size);
|
ecma_dealloc_extended_object (object_p, ext_object_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -584,7 +597,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
|| object_type == ECMA_OBJECT_TYPE_ARRAY
|
|| object_type == ECMA_OBJECT_TYPE_ARRAY
|
||||||
|| object_type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
|| object_type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||||
{
|
{
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p, ext_object_size);
|
ecma_dealloc_extended_object (object_p, ext_object_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -596,10 +609,25 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
ecma_bytecode_deref (ECMA_GET_INTERNAL_VALUE_POINTER (ecma_compiled_code_t,
|
||||||
ext_func_p->u.function.bytecode_cp));
|
ext_func_p->u.function.bytecode_cp));
|
||||||
|
|
||||||
ecma_dealloc_extended_object (ext_func_p, sizeof (ecma_extended_object_t));
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (object_type == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
|
||||||
|
|
||||||
|
ecma_bytecode_deref (ECMA_GET_NON_NULL_POINTER (ecma_compiled_code_t,
|
||||||
|
arrow_func_p->bytecode_cp));
|
||||||
|
|
||||||
|
ecma_free_value_if_not_object (arrow_func_p->this_binding);
|
||||||
|
|
||||||
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_arrow_function_t));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
if (object_type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
|
if (object_type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
|
||||||
{
|
{
|
||||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p;
|
||||||
@@ -621,20 +649,18 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
|
size_t formal_params_size = formal_params_number * sizeof (jmem_cpointer_t);
|
||||||
ecma_dealloc_extended_object (ext_object_p, sizeof (ecma_extended_object_t) + formal_params_size);
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t) + formal_params_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
|
#ifndef CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN
|
||||||
case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
|
case ECMA_PSEUDO_ARRAY_TYPEDARRAY:
|
||||||
{
|
{
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p,
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
|
||||||
sizeof (ecma_extended_object_t));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
|
case ECMA_PSEUDO_ARRAY_TYPEDARRAY_WITH_INFO:
|
||||||
{
|
{
|
||||||
ecma_dealloc_extended_object ((ecma_extended_object_t *) object_p,
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_typedarray_object_t));
|
||||||
sizeof (ecma_extended_typedarray_object_t));
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
#endif /* !CONFIG_DISABLE_ES2015_TYPEDARRAY_BUILTIN */
|
||||||
@@ -657,7 +683,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
if (!ecma_is_value_integer_number (args_len_or_this))
|
if (!ecma_is_value_integer_number (args_len_or_this))
|
||||||
{
|
{
|
||||||
ecma_free_value_if_not_object (args_len_or_this);
|
ecma_free_value_if_not_object (args_len_or_this);
|
||||||
ecma_dealloc_extended_object (ext_function_p, sizeof (ecma_extended_object_t));
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -670,7 +696,7 @@ ecma_gc_free_object (ecma_object_t *object_p) /**< object to free */
|
|||||||
}
|
}
|
||||||
|
|
||||||
size_t args_size = ((size_t) args_length) * sizeof (ecma_value_t);
|
size_t args_size = ((size_t) args_length) * sizeof (ecma_value_t);
|
||||||
ecma_dealloc_extended_object (ext_function_p, sizeof (ecma_extended_object_t) + args_size);
|
ecma_dealloc_extended_object (object_p, sizeof (ecma_extended_object_t) + args_size);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -574,18 +574,20 @@ typedef enum
|
|||||||
*/
|
*/
|
||||||
typedef enum
|
typedef enum
|
||||||
{
|
{
|
||||||
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not String (15.5),
|
ECMA_OBJECT_TYPE_GENERAL = 0, /**< all objects that are not belongs to the sub-types below. */
|
||||||
* Function (15.3), Arguments (10.6), Array (15.4) objects */
|
|
||||||
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
|
ECMA_OBJECT_TYPE_CLASS = 1, /**< Objects with class property */
|
||||||
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */
|
ECMA_OBJECT_TYPE_FUNCTION = 2, /**< Function objects (15.3), created through 13.2 routine */
|
||||||
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */
|
ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION = 3, /**< External (host) function object */
|
||||||
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */
|
ECMA_OBJECT_TYPE_ARRAY = 4, /**< Array object (15.4) */
|
||||||
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
|
ECMA_OBJECT_TYPE_BOUND_FUNCTION = 5, /**< Function objects (15.3), created through 15.3.4.5 routine */
|
||||||
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 6, /**< Array-like object, such as Arguments object (10.6) */
|
ECMA_OBJECT_TYPE_PSEUDO_ARRAY = 6, /**< Array-like object, such as Arguments object (10.6) */
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
ECMA_OBJECT_TYPE_ARROW_FUNCTION = 7, /**< arrow function objects */
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
|
/* Types between 13-15 cannot have a built-in flag. See ecma_lexical_environment_type_t. */
|
||||||
|
|
||||||
ECMA_OBJECT_TYPE__MAX = ECMA_OBJECT_TYPE_PSEUDO_ARRAY /**< maximum value */
|
ECMA_OBJECT_TYPE__MAX /**< maximum value */
|
||||||
} ecma_object_type_t;
|
} ecma_object_type_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -777,6 +779,21 @@ typedef struct
|
|||||||
ecma_built_in_props_t built_in; /**< built-in object part */
|
ecma_built_in_props_t built_in; /**< built-in object part */
|
||||||
} ecma_extended_built_in_object_t;
|
} ecma_extended_built_in_object_t;
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Description of arrow function objects.
|
||||||
|
*/
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
ecma_object_t object; /**< object header */
|
||||||
|
ecma_value_t this_binding; /**< value of 'this' binding */
|
||||||
|
jmem_cpointer_t scope_cp; /**< function scope */
|
||||||
|
jmem_cpointer_t bytecode_cp; /**< function byte code */
|
||||||
|
} ecma_arrow_function_t;
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Description of ECMA property descriptor
|
* Description of ECMA property descriptor
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ JERRY_STATIC_ASSERT (ECMA_PROPERTY_TYPE_MASK >= ECMA_PROPERTY_TYPE__MAX,
|
|||||||
/**
|
/**
|
||||||
* The ecma object types must be lower than the container mask.
|
* The ecma object types must be lower than the container mask.
|
||||||
*/
|
*/
|
||||||
JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_OBJECT_TYPE__MAX,
|
JERRY_STATIC_ASSERT (ECMA_OBJECT_TYPE_MASK >= ECMA_OBJECT_TYPE__MAX - 1,
|
||||||
ecma_object_types_must_be_lower_than_the_container_mask);
|
ecma_object_types_must_be_lower_than_the_container_mask);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -34,6 +34,22 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks whether the type is a normal or arrow function.
|
||||||
|
*
|
||||||
|
* @return true - if the type is a normal or arrow function;
|
||||||
|
* false - otherwise
|
||||||
|
*/
|
||||||
|
inline bool __attr_always_inline___
|
||||||
|
ecma_is_normal_or_arrow_function (ecma_object_type_t type)
|
||||||
|
{
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
return (type == ECMA_OBJECT_TYPE_FUNCTION || type == ECMA_OBJECT_TYPE_ARROW_FUNCTION);
|
||||||
|
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
return (type == ECMA_OBJECT_TYPE_FUNCTION);
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
} /* ecma_is_normal_or_arrow_function */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* IsCallable operation.
|
* IsCallable operation.
|
||||||
*
|
*
|
||||||
@@ -55,13 +71,18 @@ ecma_op_is_callable (ecma_value_t value) /**< ecma value */
|
|||||||
JERRY_ASSERT (obj_p != NULL);
|
JERRY_ASSERT (obj_p != NULL);
|
||||||
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
JERRY_ASSERT (!ecma_is_lexical_environment (obj_p));
|
||||||
|
|
||||||
return (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||||
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|
|
||||||
|| ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
return (type == ECMA_OBJECT_TYPE_FUNCTION
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
|| type == ECMA_OBJECT_TYPE_ARROW_FUNCTION
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|
||||||
|
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||||
} /* ecma_op_is_callable */
|
} /* ecma_op_is_callable */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check whether the value is Object that implements [[Construct]].
|
* Checks whether the value is Object that implements [[Construct]].
|
||||||
*
|
*
|
||||||
* @return true - if value is constructor object;
|
* @return true - if value is constructor object;
|
||||||
* false - otherwise
|
* false - otherwise
|
||||||
@@ -142,6 +163,42 @@ ecma_op_create_function_object (ecma_object_t *scope_p, /**< function's scope */
|
|||||||
return func_p;
|
return func_p;
|
||||||
} /* ecma_op_create_function_object */
|
} /* ecma_op_create_function_object */
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arrow function object creation operation.
|
||||||
|
*
|
||||||
|
* See also: ES2015, 9.2.12
|
||||||
|
*
|
||||||
|
* @return pointer to newly created Function object
|
||||||
|
*/
|
||||||
|
ecma_object_t *
|
||||||
|
ecma_op_create_arrow_function_object (ecma_object_t *scope_p, /**< function's scope */
|
||||||
|
const ecma_compiled_code_t *bytecode_data_p, /**< byte-code array */
|
||||||
|
ecma_value_t this_binding) /**< value of 'this' binding */
|
||||||
|
{
|
||||||
|
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||||
|
|
||||||
|
ecma_object_t *func_p = ecma_create_object (prototype_obj_p,
|
||||||
|
sizeof (ecma_arrow_function_t),
|
||||||
|
ECMA_OBJECT_TYPE_ARROW_FUNCTION);
|
||||||
|
|
||||||
|
ecma_deref_object (prototype_obj_p);
|
||||||
|
|
||||||
|
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_p;
|
||||||
|
|
||||||
|
ECMA_SET_NON_NULL_POINTER (arrow_func_p->scope_cp, scope_p);
|
||||||
|
|
||||||
|
ECMA_SET_NON_NULL_POINTER (arrow_func_p->bytecode_cp, bytecode_data_p);
|
||||||
|
ecma_bytecode_ref ((ecma_compiled_code_t *) bytecode_data_p);
|
||||||
|
|
||||||
|
arrow_func_p->this_binding = ecma_copy_value_if_not_object (this_binding);
|
||||||
|
return func_p;
|
||||||
|
} /* ecma_op_create_arrow_function_object */
|
||||||
|
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* External function object creation operation.
|
* External function object creation operation.
|
||||||
*
|
*
|
||||||
@@ -192,57 +249,7 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
|
|||||||
JERRY_ASSERT (func_obj_p != NULL
|
JERRY_ASSERT (func_obj_p != NULL
|
||||||
&& !ecma_is_lexical_environment (func_obj_p));
|
&& !ecma_is_lexical_environment (func_obj_p));
|
||||||
|
|
||||||
ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY);
|
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
|
||||||
|
|
||||||
if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_FUNCTION
|
|
||||||
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
|
||||||
{
|
|
||||||
if (!ecma_is_value_object (value))
|
|
||||||
{
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
|
|
||||||
|
|
||||||
ecma_string_t *prototype_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_PROTOTYPE);
|
|
||||||
|
|
||||||
ECMA_TRY_CATCH (prototype_obj_value,
|
|
||||||
ecma_op_object_get (func_obj_p, prototype_magic_string_p),
|
|
||||||
ret_value);
|
|
||||||
|
|
||||||
if (!ecma_is_value_object (prototype_obj_value))
|
|
||||||
{
|
|
||||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Object expected."));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
|
|
||||||
JERRY_ASSERT (prototype_obj_p != NULL);
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
|
||||||
v_obj_p = ecma_get_object_prototype (v_obj_p);
|
|
||||||
|
|
||||||
if (v_obj_p == NULL)
|
|
||||||
{
|
|
||||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
else if (v_obj_p == prototype_obj_p)
|
|
||||||
{
|
|
||||||
ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_TRUE);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} while (true);
|
|
||||||
}
|
|
||||||
|
|
||||||
ECMA_FINALIZE (prototype_obj_value);
|
|
||||||
|
|
||||||
ecma_deref_ecma_string (prototype_magic_string_p);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
JERRY_ASSERT (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||||
|
|
||||||
@@ -254,10 +261,57 @@ ecma_op_function_has_instance (ecma_object_t *func_obj_p, /**< Function object *
|
|||||||
ext_function_p->u.bound_function.target_function);
|
ext_function_p->u.bound_function.target_function);
|
||||||
|
|
||||||
/* 3. */
|
/* 3. */
|
||||||
ret_value = ecma_op_object_has_instance (target_func_obj_p, value);
|
return ecma_op_object_has_instance (target_func_obj_p, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_value;
|
JERRY_ASSERT (ecma_is_normal_or_arrow_function (ecma_get_object_type (func_obj_p))
|
||||||
|
|| ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION);
|
||||||
|
|
||||||
|
if (!ecma_is_value_object (value))
|
||||||
|
{
|
||||||
|
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_object_t *v_obj_p = ecma_get_object_from_value (value);
|
||||||
|
|
||||||
|
ecma_string_t prototype_magic_string;
|
||||||
|
ecma_init_ecma_magic_string (&prototype_magic_string, LIT_MAGIC_STRING_PROTOTYPE);
|
||||||
|
|
||||||
|
ecma_value_t prototype_obj_value = ecma_op_object_get (func_obj_p, &prototype_magic_string);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (prototype_obj_value))
|
||||||
|
{
|
||||||
|
return prototype_obj_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!ecma_is_value_object (prototype_obj_value))
|
||||||
|
{
|
||||||
|
return ecma_raise_type_error (ECMA_ERR_MSG ("Object expected."));
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_object_t *prototype_obj_p = ecma_get_object_from_value (prototype_obj_value);
|
||||||
|
JERRY_ASSERT (prototype_obj_p != NULL);
|
||||||
|
|
||||||
|
bool result = false;
|
||||||
|
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
v_obj_p = ecma_get_object_prototype (v_obj_p);
|
||||||
|
|
||||||
|
if (v_obj_p == NULL)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (v_obj_p == prototype_obj_p)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_deref_object (prototype_obj_p);
|
||||||
|
return ecma_make_boolean_value (result);
|
||||||
} /* ecma_op_function_has_instance */
|
} /* ecma_op_function_has_instance */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -364,6 +418,48 @@ ecma_op_function_call (ecma_object_t *func_obj_p, /**< Function object */
|
|||||||
ecma_free_value (this_binding);
|
ecma_free_value (this_binding);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
/* Entering Function Code (ES2015, 9.2.1) */
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) func_obj_p;
|
||||||
|
|
||||||
|
ecma_object_t *scope_p = ECMA_GET_NON_NULL_POINTER (ecma_object_t,
|
||||||
|
arrow_func_p->scope_cp);
|
||||||
|
|
||||||
|
bool is_no_lex_env;
|
||||||
|
|
||||||
|
const ecma_compiled_code_t *bytecode_data_p;
|
||||||
|
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
|
||||||
|
arrow_func_p->bytecode_cp);
|
||||||
|
|
||||||
|
is_no_lex_env = (bytecode_data_p->status_flags & CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED) ? true : false;
|
||||||
|
|
||||||
|
ecma_object_t *local_env_p;
|
||||||
|
if (is_no_lex_env)
|
||||||
|
{
|
||||||
|
local_env_p = scope_p;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
local_env_p = ecma_create_decl_lex_env (scope_p);
|
||||||
|
|
||||||
|
JERRY_ASSERT (!(bytecode_data_p->status_flags & CBC_CODE_FLAGS_ARGUMENTS_NEEDED));
|
||||||
|
}
|
||||||
|
|
||||||
|
ret_value = vm_run (bytecode_data_p,
|
||||||
|
arrow_func_p->this_binding,
|
||||||
|
local_env_p,
|
||||||
|
false,
|
||||||
|
arguments_list_p,
|
||||||
|
arguments_list_len);
|
||||||
|
|
||||||
|
if (!is_no_lex_env)
|
||||||
|
{
|
||||||
|
ecma_deref_object (local_env_p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
else if (ecma_get_object_type (func_obj_p) == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION)
|
||||||
{
|
{
|
||||||
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
|
ecma_extended_object_t *ext_func_obj_p = (ecma_extended_object_t *) func_obj_p;
|
||||||
|
|||||||
@@ -26,12 +26,20 @@
|
|||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
bool ecma_is_normal_or_arrow_function (ecma_object_type_t type);
|
||||||
|
|
||||||
bool ecma_op_is_callable (ecma_value_t value);
|
bool ecma_op_is_callable (ecma_value_t value);
|
||||||
bool ecma_is_constructor (ecma_value_t value);
|
bool ecma_is_constructor (ecma_value_t value);
|
||||||
|
|
||||||
ecma_object_t *
|
ecma_object_t *
|
||||||
ecma_op_create_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
|
ecma_op_create_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p);
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
ecma_object_t *
|
||||||
|
ecma_op_create_arrow_function_object (ecma_object_t *scope_p, const ecma_compiled_code_t *bytecode_data_p,
|
||||||
|
ecma_value_t this_binding);
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
ecma_object_t *
|
ecma_object_t *
|
||||||
ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
|
ecma_op_create_external_function_object (ecma_external_handler_t handler_cb);
|
||||||
|
|
||||||
|
|||||||
@@ -50,13 +50,7 @@
|
|||||||
*/
|
*/
|
||||||
#ifndef JERRY_NDEBUG
|
#ifndef JERRY_NDEBUG
|
||||||
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) \
|
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type) \
|
||||||
JERRY_ASSERT (type == ECMA_OBJECT_TYPE_GENERAL \
|
JERRY_ASSERT (type < ECMA_OBJECT_TYPE__MAX);
|
||||||
|| type == ECMA_OBJECT_TYPE_CLASS \
|
|
||||||
|| type == ECMA_OBJECT_TYPE_FUNCTION \
|
|
||||||
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION \
|
|
||||||
|| type == ECMA_OBJECT_TYPE_ARRAY \
|
|
||||||
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION \
|
|
||||||
|| type == ECMA_OBJECT_TYPE_PSEUDO_ARRAY);
|
|
||||||
#else /* JERRY_NDEBUG */
|
#else /* JERRY_NDEBUG */
|
||||||
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type)
|
#define JERRY_ASSERT_OBJECT_TYPE_IS_VALID(type)
|
||||||
#endif /* !JERRY_NDEBUG */
|
#endif /* !JERRY_NDEBUG */
|
||||||
@@ -199,18 +193,33 @@ ecma_op_object_get_own_property (ecma_object_t *object_p, /**< the object */
|
|||||||
{
|
{
|
||||||
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
||||||
}
|
}
|
||||||
else if (type == ECMA_OBJECT_TYPE_FUNCTION)
|
else if (ecma_is_normal_or_arrow_function (type))
|
||||||
{
|
{
|
||||||
if (ecma_string_is_length (property_name_p))
|
if (ecma_string_is_length (property_name_p))
|
||||||
{
|
{
|
||||||
if (options & ECMA_PROPERTY_GET_VALUE)
|
if (options & ECMA_PROPERTY_GET_VALUE)
|
||||||
{
|
{
|
||||||
/* Get length virtual property. */
|
/* Get length virtual property. */
|
||||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_data_p;
|
const ecma_compiled_code_t *bytecode_data_p;
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (type != ECMA_OBJECT_TYPE_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||||
|
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
||||||
|
ext_func_p->u.function.bytecode_cp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
|
||||||
|
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
|
||||||
|
arrow_func_p->bytecode_cp);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||||
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
||||||
ext_func_p->u.function.bytecode_cp);
|
ext_func_p->u.function.bytecode_cp);
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
@@ -510,16 +519,31 @@ ecma_op_object_find_own (ecma_value_t base_value, /**< base value */
|
|||||||
{
|
{
|
||||||
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
||||||
}
|
}
|
||||||
else if (type == ECMA_OBJECT_TYPE_FUNCTION)
|
else if (ecma_is_normal_or_arrow_function (type))
|
||||||
{
|
{
|
||||||
if (ecma_string_is_length (property_name_p))
|
if (ecma_string_is_length (property_name_p))
|
||||||
{
|
{
|
||||||
/* Get length virtual property. */
|
/* Get length virtual property. */
|
||||||
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
|
||||||
|
|
||||||
const ecma_compiled_code_t *bytecode_data_p;
|
const ecma_compiled_code_t *bytecode_data_p;
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (type != ECMA_OBJECT_TYPE_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||||
|
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
||||||
|
ext_func_p->u.function.bytecode_cp);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
ecma_arrow_function_t *arrow_func_p = (ecma_arrow_function_t *) object_p;
|
||||||
|
bytecode_data_p = ECMA_GET_NON_NULL_POINTER (const ecma_compiled_code_t,
|
||||||
|
arrow_func_p->bytecode_cp);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
ecma_extended_object_t *ext_func_p = (ecma_extended_object_t *) object_p;
|
||||||
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
bytecode_data_p = ECMA_GET_INTERNAL_VALUE_POINTER (const ecma_compiled_code_t,
|
||||||
ext_func_p->u.function.bytecode_cp);
|
ext_func_p->u.function.bytecode_cp);
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
uint32_t len;
|
uint32_t len;
|
||||||
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
if (bytecode_data_p->status_flags & CBC_CODE_FLAGS_UINT16_ARGUMENTS)
|
||||||
@@ -824,7 +848,7 @@ ecma_op_object_put (ecma_object_t *object_p, /**< the object */
|
|||||||
{
|
{
|
||||||
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
property_p = ecma_builtin_try_to_instantiate_property (object_p, property_name_p);
|
||||||
}
|
}
|
||||||
else if (type == ECMA_OBJECT_TYPE_FUNCTION)
|
else if (ecma_is_normal_or_arrow_function (type))
|
||||||
{
|
{
|
||||||
if (ecma_string_is_length (property_name_p))
|
if (ecma_string_is_length (property_name_p))
|
||||||
{
|
{
|
||||||
@@ -985,48 +1009,23 @@ ecma_op_object_delete (ecma_object_t *obj_p, /**< the object */
|
|||||||
&& !ecma_is_lexical_environment (obj_p));
|
&& !ecma_is_lexical_environment (obj_p));
|
||||||
JERRY_ASSERT (property_name_p != NULL);
|
JERRY_ASSERT (property_name_p != NULL);
|
||||||
|
|
||||||
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_PSEUDO_ARRAY)
|
||||||
|
|
||||||
switch (type)
|
|
||||||
{
|
{
|
||||||
case ECMA_OBJECT_TYPE_GENERAL:
|
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
||||||
case ECMA_OBJECT_TYPE_CLASS:
|
|
||||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
|
||||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
|
||||||
case ECMA_OBJECT_TYPE_ARRAY:
|
|
||||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
|
||||||
{
|
|
||||||
return ecma_op_general_object_delete (obj_p,
|
|
||||||
property_name_p,
|
|
||||||
is_throw);
|
|
||||||
}
|
|
||||||
|
|
||||||
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
|
if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS)
|
||||||
{
|
{
|
||||||
ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p;
|
return ecma_op_arguments_object_delete (obj_p,
|
||||||
|
|
||||||
if (ext_object_p->u.pseudo_array.type == ECMA_PSEUDO_ARRAY_ARGUMENTS)
|
|
||||||
{
|
|
||||||
return ecma_op_arguments_object_delete (obj_p,
|
|
||||||
property_name_p,
|
|
||||||
is_throw);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ecma_op_general_object_delete (obj_p,
|
|
||||||
property_name_p,
|
property_name_p,
|
||||||
is_throw);
|
is_throw);
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (false);
|
|
||||||
|
|
||||||
return ecma_make_simple_value (ECMA_SIMPLE_VALUE_FALSE);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JERRY_ASSERT_OBJECT_TYPE_IS_VALID (ecma_get_object_type (obj_p));
|
||||||
|
|
||||||
|
return ecma_op_general_object_delete (obj_p,
|
||||||
|
property_name_p,
|
||||||
|
is_throw);
|
||||||
} /* ecma_op_object_delete */
|
} /* ecma_op_object_delete */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1058,6 +1057,7 @@ ecma_op_object_default_value (ecma_object_t *obj_p, /**< the object */
|
|||||||
* [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value,
|
* [ECMA_OBJECT_TYPE_ARRAY] = &ecma_op_general_object_default_value,
|
||||||
* [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value,
|
* [ECMA_OBJECT_TYPE_BOUND_FUNCTION] = &ecma_op_general_object_default_value,
|
||||||
* [ECMA_OBJECT_TYPE_PSEUDO_ARRAY] = &ecma_op_general_object_default_value
|
* [ECMA_OBJECT_TYPE_PSEUDO_ARRAY] = &ecma_op_general_object_default_value
|
||||||
|
* [ECMA_OBJECT_TYPE_ARROW_FUNCTION] = &ecma_op_general_object_default_value
|
||||||
* };
|
* };
|
||||||
*
|
*
|
||||||
* return default_value[type] (obj_p, property_name_p);
|
* return default_value[type] (obj_p, property_name_p);
|
||||||
@@ -1093,6 +1093,9 @@ ecma_op_object_define_own_property (ecma_object_t *obj_p, /**< the object */
|
|||||||
case ECMA_OBJECT_TYPE_GENERAL:
|
case ECMA_OBJECT_TYPE_GENERAL:
|
||||||
case ECMA_OBJECT_TYPE_CLASS:
|
case ECMA_OBJECT_TYPE_CLASS:
|
||||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
case ECMA_OBJECT_TYPE_ARROW_FUNCTION:
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||||
{
|
{
|
||||||
@@ -1263,29 +1266,16 @@ ecma_op_object_has_instance (ecma_object_t *obj_p, /**< the object */
|
|||||||
|
|
||||||
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
const ecma_object_type_t type = ecma_get_object_type (obj_p);
|
||||||
|
|
||||||
switch (type)
|
if (ecma_is_normal_or_arrow_function (type)
|
||||||
|
|| type == ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION
|
||||||
|
|| type == ECMA_OBJECT_TYPE_BOUND_FUNCTION)
|
||||||
{
|
{
|
||||||
case ECMA_OBJECT_TYPE_GENERAL:
|
return ecma_op_function_has_instance (obj_p, value);
|
||||||
case ECMA_OBJECT_TYPE_CLASS:
|
|
||||||
case ECMA_OBJECT_TYPE_ARRAY:
|
|
||||||
case ECMA_OBJECT_TYPE_PSEUDO_ARRAY:
|
|
||||||
{
|
|
||||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function object."));
|
|
||||||
}
|
|
||||||
|
|
||||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
|
||||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
|
||||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
|
||||||
{
|
|
||||||
return ecma_op_function_has_instance (obj_p, value);
|
|
||||||
}
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
JERRY_UNREACHABLE ();
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JERRY_ASSERT_OBJECT_TYPE_IS_VALID (type);
|
||||||
|
|
||||||
|
return ecma_raise_type_error (ECMA_ERR_MSG ("Expected a function object."));
|
||||||
} /* ecma_op_object_has_instance */
|
} /* ecma_op_object_has_instance */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -1387,6 +1377,9 @@ ecma_op_object_get_property_names (ecma_object_t *obj_p, /**< object */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
case ECMA_OBJECT_TYPE_ARROW_FUNCTION:
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
{
|
{
|
||||||
ecma_op_function_list_lazy_property_names (obj_p,
|
ecma_op_function_list_lazy_property_names (obj_p,
|
||||||
is_enumerable_only,
|
is_enumerable_only,
|
||||||
@@ -1782,6 +1775,9 @@ ecma_object_get_class_name (ecma_object_t *obj_p) /**< object */
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ECMA_OBJECT_TYPE_FUNCTION:
|
case ECMA_OBJECT_TYPE_FUNCTION:
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
case ECMA_OBJECT_TYPE_ARROW_FUNCTION:
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
case ECMA_OBJECT_TYPE_EXTERNAL_FUNCTION:
|
||||||
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
case ECMA_OBJECT_TYPE_BOUND_FUNCTION:
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -654,6 +654,9 @@ typedef enum
|
|||||||
CBC_CODE_FLAGS_ARGUMENTS_NEEDED = (1u << 4), /**< arguments object must be constructed */
|
CBC_CODE_FLAGS_ARGUMENTS_NEEDED = (1u << 4), /**< arguments object must be constructed */
|
||||||
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED = (1u << 5), /**< no need to create a lexical environment */
|
||||||
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 6), /**< this function should be ignored by debugger */
|
CBC_CODE_FLAGS_DEBUGGER_IGNORE = (1u << 6), /**< this function should be ignored by debugger */
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
CBC_CODE_FLAGS_ARROW_FUNCTION = (1u << 6), /**< this function is an arrow function */
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
} cbc_code_flags;
|
} cbc_code_flags;
|
||||||
|
|
||||||
#define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
|
#define CBC_OPCODE(arg1, arg2, arg3, arg4) arg1,
|
||||||
|
|||||||
@@ -1190,6 +1190,13 @@ parse_print_final_cbc (ecma_compiled_code_t *compiled_code_p, /**< compiled code
|
|||||||
JERRY_DEBUG_MSG (",no_lexical_env");
|
JERRY_DEBUG_MSG (",no_lexical_env");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (compiled_code_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
JERRY_DEBUG_MSG (",arrow");
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
JERRY_DEBUG_MSG ("]\n");
|
JERRY_DEBUG_MSG ("]\n");
|
||||||
|
|
||||||
JERRY_DEBUG_MSG (" Argument range end: %d\n", (int) argument_end);
|
JERRY_DEBUG_MSG (" Argument range end: %d\n", (int) argument_end);
|
||||||
@@ -1666,6 +1673,13 @@ parser_post_processing (parser_context_t *context_p) /**< context */
|
|||||||
compiled_code_p->status_flags |= CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED;
|
compiled_code_p->status_flags |= CBC_CODE_FLAGS_LEXICAL_ENV_NOT_NEEDED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (context_p->status_flags & PARSER_IS_ARROW_FUNCTION)
|
||||||
|
{
|
||||||
|
compiled_code_p->status_flags |= CBC_CODE_FLAGS_ARROW_FUNCTION;
|
||||||
|
}
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
literal_pool_p = (jmem_cpointer_t *) byte_code_p;
|
literal_pool_p = (jmem_cpointer_t *) byte_code_p;
|
||||||
byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t);
|
byte_code_p += context_p->literal_count * sizeof (jmem_cpointer_t);
|
||||||
|
|
||||||
|
|||||||
+18
-2
@@ -302,8 +302,24 @@ vm_construct_literal_object (vm_frame_ctx_t *frame_ctx_p, /**< frame context */
|
|||||||
|
|
||||||
if (is_function)
|
if (is_function)
|
||||||
{
|
{
|
||||||
ecma_object_t *func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
|
ecma_object_t *func_obj_p;
|
||||||
bytecode_p);
|
|
||||||
|
#ifndef CONFIG_DISABLE_ES2015_ARROW_FUNCTION
|
||||||
|
if (!(bytecode_p->status_flags & CBC_CODE_FLAGS_ARROW_FUNCTION))
|
||||||
|
{
|
||||||
|
func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
|
||||||
|
bytecode_p);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
func_obj_p = ecma_op_create_arrow_function_object (frame_ctx_p->lex_env_p,
|
||||||
|
bytecode_p,
|
||||||
|
frame_ctx_p->this_binding);
|
||||||
|
}
|
||||||
|
#else /* CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
func_obj_p = ecma_op_create_function_object (frame_ctx_p->lex_env_p,
|
||||||
|
bytecode_p);
|
||||||
|
#endif /* !CONFIG_DISABLE_ES2015_ARROW_FUNCTION */
|
||||||
|
|
||||||
return ecma_make_object_value (func_obj_p);
|
return ecma_make_object_value (func_obj_p);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
/* Copyright JS Foundation and other contributors, http://js.foundation
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var o = {
|
||||||
|
x: 13,
|
||||||
|
|
||||||
|
f: function()
|
||||||
|
{
|
||||||
|
return () => this.x + 1
|
||||||
|
},
|
||||||
|
|
||||||
|
g: function()
|
||||||
|
{
|
||||||
|
return function() {
|
||||||
|
return this.x + 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(o.f().call(o) === 14);
|
||||||
|
assert(o.g().call(o) === 14);
|
||||||
|
|
||||||
|
assert(o.f()() === 14);
|
||||||
|
|
||||||
|
var o2 = { x:4, f:o.f(), g:o.g() }
|
||||||
|
|
||||||
|
assert(o2.f() === 14);
|
||||||
|
assert(o2.g() === 5);
|
||||||
Reference in New Issue
Block a user