Use custom dispatcher for Function.prototype routines (#2967)
Binary size gain:
- Intel: ~70B (gcc-7.3)
- Arm: 50 B (arm-linux-gnueabi-gcc-7.3)
Co-authored-by: Gabor Loki loki@inf.u-szeged.hu
JerryScript-DCO-1.0-Signed-off-by: Robert Fancsik frobert@inf.u-szeged.hu
This commit is contained in:
committed by
Dániel Bátyai
parent
c0b8845530
commit
7aa3bfdc6d
@@ -29,6 +29,23 @@
|
|||||||
#define ECMA_BUILTINS_INTERNAL
|
#define ECMA_BUILTINS_INTERNAL
|
||||||
#include "ecma-builtins-internal.h"
|
#include "ecma-builtins-internal.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This object has a custom dispatch function.
|
||||||
|
*/
|
||||||
|
#define BUILTIN_CUSTOM_DISPATCH
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of built-in routine identifiers.
|
||||||
|
*/
|
||||||
|
enum
|
||||||
|
{
|
||||||
|
ECMA_FUNCTION_PROTOTYPE_ROUTINE_START = ECMA_BUILTIN_ID__COUNT - 1,
|
||||||
|
ECMA_FUNCTION_PROTOTYPE_TO_STRING,
|
||||||
|
ECMA_FUNCTION_PROTOTYPE_CALL,
|
||||||
|
ECMA_FUNCTION_PROTOTYPE_APPLY,
|
||||||
|
ECMA_FUNCTION_PROTOTYPE_BIND,
|
||||||
|
};
|
||||||
|
|
||||||
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-function-prototype.inc.h"
|
#define BUILTIN_INC_HEADER_NAME "ecma-builtin-function-prototype.inc.h"
|
||||||
#define BUILTIN_UNDERSCORED_ID function_prototype
|
#define BUILTIN_UNDERSCORED_ID function_prototype
|
||||||
#include "ecma-builtin-internal-routines-template.inc.h"
|
#include "ecma-builtin-internal-routines-template.inc.h"
|
||||||
@@ -58,19 +75,9 @@
|
|||||||
* Returned value must be freed with ecma_free_value.
|
* Returned value must be freed with ecma_free_value.
|
||||||
*/
|
*/
|
||||||
static ecma_value_t
|
static ecma_value_t
|
||||||
ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */
|
ecma_builtin_function_prototype_object_to_string (void)
|
||||||
{
|
{
|
||||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
return ecma_make_magic_string_value (LIT_MAGIC_STRING__FUNCTION_TO_STRING);
|
||||||
|
|
||||||
if (!ecma_op_is_callable (this_arg))
|
|
||||||
{
|
|
||||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__FUNCTION_TO_STRING);
|
|
||||||
}
|
|
||||||
return ret_value;
|
|
||||||
} /* ecma_builtin_function_prototype_object_to_string */
|
} /* ecma_builtin_function_prototype_object_to_string */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -83,104 +90,87 @@ ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< th
|
|||||||
* Returned value must be freed with ecma_free_value.
|
* Returned value must be freed with ecma_free_value.
|
||||||
*/
|
*/
|
||||||
static ecma_value_t
|
static ecma_value_t
|
||||||
ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this argument */
|
ecma_builtin_function_prototype_object_apply (ecma_object_t *func_obj_p, /**< this argument object */
|
||||||
ecma_value_t arg1, /**< first argument */
|
ecma_value_t arg1, /**< first argument */
|
||||||
ecma_value_t arg2) /**< second argument */
|
ecma_value_t arg2) /**< second argument */
|
||||||
{
|
{
|
||||||
|
/* 2. */
|
||||||
|
if (ecma_is_value_null (arg2) || ecma_is_value_undefined (arg2))
|
||||||
|
{
|
||||||
|
return ecma_op_function_call (func_obj_p, arg1, NULL, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 3. */
|
||||||
|
if (!ecma_is_value_object (arg2))
|
||||||
|
{
|
||||||
|
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
|
||||||
|
|
||||||
|
/* 4. */
|
||||||
|
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
|
||||||
|
if (ECMA_IS_VALUE_ERROR (length_value))
|
||||||
|
{
|
||||||
|
return length_value;
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_number_t length_number;
|
||||||
|
ecma_value_t get_result = ecma_get_number (length_value, &length_number);
|
||||||
|
|
||||||
|
ecma_free_value (length_value);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (get_result))
|
||||||
|
{
|
||||||
|
return get_result;
|
||||||
|
}
|
||||||
|
JERRY_ASSERT (ecma_is_value_empty (get_result));
|
||||||
|
|
||||||
|
/* 5. */
|
||||||
|
const uint32_t length = ecma_number_to_uint32 (length_number);
|
||||||
|
|
||||||
|
if (length >= ECMA_FUNCTION_APPLY_ARGUMENT_COUNT_LIMIT)
|
||||||
|
{
|
||||||
|
return ecma_raise_range_error (ECMA_ERR_MSG ("Too many arguments declared for Function.apply()."));
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 6. */
|
||||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
||||||
|
JMEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t);
|
||||||
|
uint32_t index = 0;
|
||||||
|
|
||||||
/* 1. */
|
/* 7. */
|
||||||
if (!ecma_op_is_callable (this_arg))
|
for (index = 0; index < length; index++)
|
||||||
{
|
{
|
||||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
|
ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);
|
||||||
|
ecma_value_t get_value = ecma_op_object_get (obj_p, curr_idx_str_p);
|
||||||
|
ecma_deref_ecma_string (curr_idx_str_p);
|
||||||
|
|
||||||
|
if (ECMA_IS_VALUE_ERROR (get_value))
|
||||||
|
{
|
||||||
|
ret_value = get_value;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
arguments_list_p[index] = get_value;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
|
if (ecma_is_value_empty (ret_value))
|
||||||
{
|
{
|
||||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);
|
JERRY_ASSERT (index == length);
|
||||||
|
ret_value = ecma_op_function_call (func_obj_p,
|
||||||
/* 2. */
|
arg1,
|
||||||
if (ecma_is_value_null (arg2) || ecma_is_value_undefined (arg2))
|
arguments_list_p,
|
||||||
{
|
length);
|
||||||
ret_value = ecma_op_function_call (func_obj_p, arg1, NULL, 0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 3. */
|
|
||||||
if (!ecma_is_value_object (arg2))
|
|
||||||
{
|
|
||||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument is not an object."));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
ecma_object_t *obj_p = ecma_get_object_from_value (arg2);
|
|
||||||
|
|
||||||
/* 4. */
|
|
||||||
ecma_value_t length_value = ecma_op_object_get_by_magic_id (obj_p, LIT_MAGIC_STRING_LENGTH);
|
|
||||||
if (ECMA_IS_VALUE_ERROR (length_value))
|
|
||||||
{
|
|
||||||
return length_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_number_t length_number;
|
|
||||||
ecma_value_t get_result = ecma_get_number (length_value, &length_number);
|
|
||||||
|
|
||||||
ecma_free_value (length_value);
|
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (get_result))
|
|
||||||
{
|
|
||||||
return get_result;
|
|
||||||
}
|
|
||||||
JERRY_ASSERT (ecma_is_value_empty (get_result));
|
|
||||||
|
|
||||||
/* 5. */
|
|
||||||
const uint32_t length = ecma_number_to_uint32 (length_number);
|
|
||||||
|
|
||||||
if (length >= ECMA_FUNCTION_APPLY_ARGUMENT_COUNT_LIMIT)
|
|
||||||
{
|
|
||||||
ret_value = ecma_raise_range_error (ECMA_ERR_MSG ("Too many arguments declared for Function.apply()."));
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* 6. */
|
|
||||||
JMEM_DEFINE_LOCAL_ARRAY (arguments_list_p, length, ecma_value_t);
|
|
||||||
uint32_t index = 0;
|
|
||||||
|
|
||||||
/* 7. */
|
|
||||||
for (index = 0; index < length; index++)
|
|
||||||
{
|
|
||||||
ecma_string_t *curr_idx_str_p = ecma_new_ecma_string_from_uint32 (index);
|
|
||||||
ecma_value_t get_value = ecma_op_object_get (obj_p, curr_idx_str_p);
|
|
||||||
ecma_deref_ecma_string (curr_idx_str_p);
|
|
||||||
|
|
||||||
if (ECMA_IS_VALUE_ERROR (get_value))
|
|
||||||
{
|
|
||||||
ret_value = get_value;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
arguments_list_p[index] = get_value;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ecma_is_value_empty (ret_value))
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (index == length);
|
|
||||||
ret_value = ecma_op_function_call (func_obj_p,
|
|
||||||
arg1,
|
|
||||||
arguments_list_p,
|
|
||||||
length);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (uint32_t remove_index = 0; remove_index < index; remove_index++)
|
|
||||||
{
|
|
||||||
ecma_free_value (arguments_list_p[remove_index]);
|
|
||||||
}
|
|
||||||
|
|
||||||
JMEM_FINALIZE_LOCAL_ARRAY (arguments_list_p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (uint32_t remove_index = 0; remove_index < index; remove_index++)
|
||||||
|
{
|
||||||
|
ecma_free_value (arguments_list_p[remove_index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
JMEM_FINALIZE_LOCAL_ARRAY (arguments_list_p);
|
||||||
|
|
||||||
return ret_value;
|
return ret_value;
|
||||||
} /* ecma_builtin_function_prototype_object_apply */
|
} /* ecma_builtin_function_prototype_object_apply */
|
||||||
|
|
||||||
@@ -194,34 +184,23 @@ ecma_builtin_function_prototype_object_apply (ecma_value_t this_arg, /**< this a
|
|||||||
* Returned value must be freed with ecma_free_value.
|
* Returned value must be freed with ecma_free_value.
|
||||||
*/
|
*/
|
||||||
static ecma_value_t
|
static ecma_value_t
|
||||||
ecma_builtin_function_prototype_object_call (ecma_value_t this_arg, /**< this argument */
|
ecma_builtin_function_prototype_object_call (ecma_object_t *func_obj_p , /**< this argument object */
|
||||||
const ecma_value_t *arguments_list_p, /**< list of arguments */
|
const ecma_value_t *arguments_list_p, /**< list of arguments */
|
||||||
ecma_length_t arguments_number) /**< number of arguments */
|
ecma_length_t arguments_number) /**< number of arguments */
|
||||||
{
|
{
|
||||||
if (!ecma_op_is_callable (this_arg))
|
if (arguments_number == 0)
|
||||||
{
|
{
|
||||||
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
|
/* Even a 'this' argument is missing. */
|
||||||
|
return ecma_op_function_call (func_obj_p,
|
||||||
|
ECMA_VALUE_UNDEFINED,
|
||||||
|
NULL,
|
||||||
|
0);
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);
|
|
||||||
|
|
||||||
if (arguments_number == 0)
|
return ecma_op_function_call (func_obj_p,
|
||||||
{
|
arguments_list_p[0],
|
||||||
/* Even a 'this' argument is missing. */
|
arguments_list_p + 1,
|
||||||
return ecma_op_function_call (func_obj_p,
|
(ecma_length_t) (arguments_number - 1u));
|
||||||
ECMA_VALUE_UNDEFINED,
|
|
||||||
NULL,
|
|
||||||
0);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return ecma_op_function_call (func_obj_p,
|
|
||||||
arguments_list_p[0],
|
|
||||||
arguments_list_p + 1,
|
|
||||||
(ecma_length_t) (arguments_number - 1u));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} /* ecma_builtin_function_prototype_object_call */
|
} /* ecma_builtin_function_prototype_object_call */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -234,86 +213,72 @@ ecma_builtin_function_prototype_object_call (ecma_value_t this_arg, /**< this ar
|
|||||||
* Returned value must be freed with ecma_free_value.
|
* Returned value must be freed with ecma_free_value.
|
||||||
*/
|
*/
|
||||||
static ecma_value_t
|
static ecma_value_t
|
||||||
ecma_builtin_function_prototype_object_bind (ecma_value_t this_arg, /**< this argument */
|
ecma_builtin_function_prototype_object_bind (ecma_object_t *this_arg_obj_p , /**< this argument object */
|
||||||
const ecma_value_t *arguments_list_p, /**< list of arguments */
|
const ecma_value_t *arguments_list_p, /**< list of arguments */
|
||||||
ecma_length_t arguments_number) /**< number of arguments */
|
ecma_length_t arguments_number) /**< number of arguments */
|
||||||
{
|
{
|
||||||
ecma_value_t ret_value = ECMA_VALUE_EMPTY;
|
/* 4. 11. 18. */
|
||||||
|
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
||||||
|
|
||||||
/* 2. */
|
ecma_object_t *function_p;
|
||||||
if (!ecma_op_is_callable (this_arg))
|
ecma_extended_object_t *ext_function_p;
|
||||||
|
|
||||||
|
if (arguments_number == 0
|
||||||
|
|| (arguments_number == 1 && !ecma_is_value_integer_number (arguments_list_p[0])))
|
||||||
{
|
{
|
||||||
ret_value = ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
|
function_p = ecma_create_object (prototype_obj_p,
|
||||||
|
sizeof (ecma_extended_object_t),
|
||||||
|
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||||
|
|
||||||
|
/* 8. */
|
||||||
|
ext_function_p = (ecma_extended_object_t *) function_p;
|
||||||
|
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
|
||||||
|
this_arg_obj_p);
|
||||||
|
|
||||||
|
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
|
||||||
|
|
||||||
|
if (arguments_number != 0)
|
||||||
|
{
|
||||||
|
ext_function_p->u.bound_function.args_len_or_this = ecma_copy_value_if_not_object (arguments_list_p[0]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* 4. 11. 18. */
|
JERRY_ASSERT (arguments_number > 0);
|
||||||
ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_FUNCTION_PROTOTYPE);
|
|
||||||
|
|
||||||
ecma_object_t *function_p;
|
size_t obj_size = sizeof (ecma_extended_object_t) + (arguments_number * sizeof (ecma_value_t));
|
||||||
ecma_extended_object_t *ext_function_p;
|
|
||||||
|
|
||||||
if (arguments_number == 0
|
function_p = ecma_create_object (prototype_obj_p,
|
||||||
|| (arguments_number == 1 && !ecma_is_value_integer_number (arguments_list_p[0])))
|
obj_size,
|
||||||
|
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
||||||
|
|
||||||
|
/* 8. */
|
||||||
|
ext_function_p = (ecma_extended_object_t *) function_p;
|
||||||
|
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
|
||||||
|
this_arg_obj_p);
|
||||||
|
|
||||||
|
/* NOTE: This solution provides temporary false data about the object's size
|
||||||
|
but prevents GC from freeing it until it's not fully initialized. */
|
||||||
|
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
|
||||||
|
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
||||||
|
|
||||||
|
for (ecma_length_t i = 0; i < arguments_number; i++)
|
||||||
{
|
{
|
||||||
function_p = ecma_create_object (prototype_obj_p,
|
*args_p++ = ecma_copy_value_if_not_object (arguments_list_p[i]);
|
||||||
sizeof (ecma_extended_object_t),
|
|
||||||
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
|
||||||
|
|
||||||
/* 8. */
|
|
||||||
ext_function_p = (ecma_extended_object_t *) function_p;
|
|
||||||
ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg);
|
|
||||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
|
|
||||||
this_arg_obj_p);
|
|
||||||
|
|
||||||
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
|
|
||||||
|
|
||||||
if (arguments_number != 0)
|
|
||||||
{
|
|
||||||
ext_function_p->u.bound_function.args_len_or_this = ecma_copy_value_if_not_object (arguments_list_p[0]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
JERRY_ASSERT (arguments_number > 0);
|
|
||||||
|
|
||||||
size_t obj_size = sizeof (ecma_extended_object_t) + (arguments_number * sizeof (ecma_value_t));
|
|
||||||
|
|
||||||
function_p = ecma_create_object (prototype_obj_p,
|
|
||||||
obj_size,
|
|
||||||
ECMA_OBJECT_TYPE_BOUND_FUNCTION);
|
|
||||||
|
|
||||||
/* 8. */
|
|
||||||
ext_function_p = (ecma_extended_object_t *) function_p;
|
|
||||||
ecma_object_t *this_arg_obj_p = ecma_get_object_from_value (this_arg);
|
|
||||||
ECMA_SET_INTERNAL_VALUE_POINTER (ext_function_p->u.bound_function.target_function,
|
|
||||||
this_arg_obj_p);
|
|
||||||
|
|
||||||
/* NOTE: This solution provides temporary false data about the object's size
|
|
||||||
but prevents GC from freeing it until it's not fully initialized. */
|
|
||||||
ext_function_p->u.bound_function.args_len_or_this = ECMA_VALUE_UNDEFINED;
|
|
||||||
ecma_value_t *args_p = (ecma_value_t *) (ext_function_p + 1);
|
|
||||||
|
|
||||||
for (ecma_length_t i = 0; i < arguments_number; i++)
|
|
||||||
{
|
|
||||||
*args_p++ = ecma_copy_value_if_not_object (arguments_list_p[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
ecma_value_t args_len_or_this = ecma_make_integer_value ((ecma_integer_value_t) arguments_number);
|
|
||||||
ext_function_p->u.bound_function.args_len_or_this = args_len_or_this;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
ecma_value_t args_len_or_this = ecma_make_integer_value ((ecma_integer_value_t) arguments_number);
|
||||||
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
|
ext_function_p->u.bound_function.args_len_or_this = args_len_or_this;
|
||||||
*
|
|
||||||
* See also: ecma_object_get_class_name
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* 22. */
|
|
||||||
ret_value = ecma_make_object_value (function_p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret_value;
|
/*
|
||||||
|
* [[Class]] property is not stored explicitly for objects of ECMA_OBJECT_TYPE_FUNCTION type.
|
||||||
|
*
|
||||||
|
* See also: ecma_object_get_class_name
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* 22. */
|
||||||
|
return ecma_make_object_value (function_p);
|
||||||
} /* ecma_builtin_function_prototype_object_bind */
|
} /* ecma_builtin_function_prototype_object_bind */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -344,6 +309,54 @@ ecma_builtin_function_prototype_dispatch_construct (const ecma_value_t *argument
|
|||||||
return ecma_raise_type_error (ECMA_ERR_MSG ("'Function.prototype' is not a constructor."));
|
return ecma_raise_type_error (ECMA_ERR_MSG ("'Function.prototype' is not a constructor."));
|
||||||
} /* ecma_builtin_function_prototype_dispatch_construct */
|
} /* ecma_builtin_function_prototype_dispatch_construct */
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Dispatcher of the built-in's routines
|
||||||
|
*
|
||||||
|
* @return ecma value
|
||||||
|
* Returned value must be freed with ecma_free_value.
|
||||||
|
*/
|
||||||
|
ecma_value_t
|
||||||
|
ecma_builtin_function_prototype_dispatch_routine (uint16_t builtin_routine_id, /**< built-in wide routine
|
||||||
|
* identifier */
|
||||||
|
ecma_value_t this_arg, /**< 'this' argument value */
|
||||||
|
const ecma_value_t arguments_list_p[], /**< list of arguments
|
||||||
|
* passed to routine */
|
||||||
|
ecma_length_t arguments_number) /**< length of arguments' list */
|
||||||
|
{
|
||||||
|
if (!ecma_op_is_callable (this_arg))
|
||||||
|
{
|
||||||
|
return ecma_raise_type_error (ECMA_ERR_MSG ("Argument 'this' is not a function."));
|
||||||
|
}
|
||||||
|
|
||||||
|
ecma_object_t *func_obj_p = ecma_get_object_from_value (this_arg);
|
||||||
|
|
||||||
|
switch (builtin_routine_id)
|
||||||
|
{
|
||||||
|
case ECMA_FUNCTION_PROTOTYPE_TO_STRING:
|
||||||
|
{
|
||||||
|
return ecma_builtin_function_prototype_object_to_string ();
|
||||||
|
}
|
||||||
|
case ECMA_FUNCTION_PROTOTYPE_APPLY:
|
||||||
|
{
|
||||||
|
return ecma_builtin_function_prototype_object_apply (func_obj_p,
|
||||||
|
arguments_list_p[0],
|
||||||
|
arguments_list_p[1]);
|
||||||
|
}
|
||||||
|
case ECMA_FUNCTION_PROTOTYPE_CALL:
|
||||||
|
{
|
||||||
|
return ecma_builtin_function_prototype_object_call (func_obj_p, arguments_list_p, arguments_number);
|
||||||
|
}
|
||||||
|
case ECMA_FUNCTION_PROTOTYPE_BIND:
|
||||||
|
{
|
||||||
|
return ecma_builtin_function_prototype_object_bind (func_obj_p, arguments_list_p, arguments_number);
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
JERRY_UNREACHABLE ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} /* ecma_builtin_function_prototype_dispatch_routine */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @}
|
* @}
|
||||||
* @}
|
* @}
|
||||||
|
|||||||
@@ -37,9 +37,9 @@ NUMBER_VALUE (LIT_MAGIC_STRING_LENGTH,
|
|||||||
|
|
||||||
/* Routine properties:
|
/* Routine properties:
|
||||||
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
* (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */
|
||||||
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ecma_builtin_function_prototype_object_to_string, 0, 0)
|
ROUTINE (LIT_MAGIC_STRING_TO_STRING_UL, ECMA_FUNCTION_PROTOTYPE_TO_STRING, 0, 0)
|
||||||
ROUTINE (LIT_MAGIC_STRING_APPLY, ecma_builtin_function_prototype_object_apply, 2, 2)
|
ROUTINE (LIT_MAGIC_STRING_APPLY, ECMA_FUNCTION_PROTOTYPE_APPLY, 2, 2)
|
||||||
ROUTINE (LIT_MAGIC_STRING_CALL, ecma_builtin_function_prototype_object_call, NON_FIXED, 1)
|
ROUTINE (LIT_MAGIC_STRING_CALL, ECMA_FUNCTION_PROTOTYPE_CALL, NON_FIXED, 1)
|
||||||
ROUTINE (LIT_MAGIC_STRING_BIND, ecma_builtin_function_prototype_object_bind, NON_FIXED, 1)
|
ROUTINE (LIT_MAGIC_STRING_BIND, ECMA_FUNCTION_PROTOTYPE_BIND, NON_FIXED, 1)
|
||||||
|
|
||||||
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
#include "ecma-builtin-helpers-macro-undefs.inc.h"
|
||||||
|
|||||||
Reference in New Issue
Block a user