diff --git a/src/libecmabuiltins/ecma-builtin-boolean-prototype-object.c b/src/libecmabuiltins/ecma-builtin-boolean-prototype-object.c index 14681bc92..bd8a76e37 100644 --- a/src/libecmabuiltins/ecma-builtin-boolean-prototype-object.c +++ b/src/libecmabuiltins/ecma-builtin-boolean-prototype-object.c @@ -38,51 +38,180 @@ * @{ */ -/** - * List of the Boolean.prototype object built-in object value properties in format 'macro (name, value)'. - */ -#define ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_OBJECT_VALUES_PROPERTY_LIST(macro) \ - macro (ECMA_MAGIC_STRING_CONSTRUCTOR, ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN)) - -/** - * List of the Boolean.prototype object built-in routine properties in format - * 'macro (name, C function name, arguments number of the routine, length value of the routine)'. - */ -#define ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_ROUTINES_PROPERTY_LIST(macro) \ - macro (ECMA_MAGIC_STRING_TO_STRING_UL, \ - ecma_builtin_boolean_prototype_object_to_string, \ - 0, \ - 0) \ - macro (ECMA_MAGIC_STRING_VALUE_OF_UL, \ - ecma_builtin_boolean_prototype_object_value_of, \ - 0, \ - 0) - #define ROUTINE_ARG_LIST_0 ecma_value_t this -#define CASE_ROUTINE_PROP_LIST(name, c_function_name, args_number, length) \ +#define ROUTINE(name, c_function_name, args_number, length_prop_value) \ static ecma_completion_value_t c_function_name (ROUTINE_ARG_LIST_ ## args_number); -ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_ROUTINES_PROPERTY_LIST (CASE_ROUTINE_PROP_LIST) -#undef CASE_ROUTINE_PROP_LIST +#include "ecma-builtin-boolean-prototype.inc.h" #undef ROUTINE_ARG_LIST_0 /** - * List of the Boolean.prototype object's built-in property names + * If the property's name is one of built-in properties of the Boolean.prototype object + * that is not instantiated yet, instantiate the property and + * return pointer to the instantiated property. + * + * @return pointer property, if one was instantiated, + * NULL - otherwise. */ -static const ecma_magic_string_id_t ecma_builtin_property_names[] = +ecma_property_t* +ecma_builtin_boolean_prototype_try_to_instantiate_property (ecma_object_t *obj_p, /**< object */ + ecma_string_t *prop_name_p) /**< property's name */ { -#define VALUE_PROP_LIST(name, value) name, -#define ROUTINE_PROP_LIST(name, c_function_name, args_number, length) name, - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_OBJECT_VALUES_PROPERTY_LIST (VALUE_PROP_LIST) - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_ROUTINES_PROPERTY_LIST (ROUTINE_PROP_LIST) -#undef VALUE_PROP_LIST -#undef ROUTINE_PROP_LIST -}; + JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE)); + JERRY_ASSERT (ecma_find_named_property (obj_p, prop_name_p) == NULL); + + ecma_magic_string_id_t id; + + if (!ecma_is_string_magic (prop_name_p, &id)) + { + return NULL; + } + + const ecma_magic_string_id_t ecma_builtin_property_names[] = + { +#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) name, +#define ROUTINE(name, c_function_name, args_number, length_prop_value) name, +#include "ecma-builtin-boolean-prototype.inc.h" + }; + + int32_t index; + index = ecma_builtin_bin_search_for_magic_string_id_in_array (ecma_builtin_property_names, + sizeof (ecma_builtin_property_names) / + sizeof (ecma_builtin_property_names [0]), + id); + + if (index == -1) + { + return NULL; + } + + JERRY_ASSERT (index >= 0 && (uint32_t) index < sizeof (uint64_t) * JERRY_BITSINBYTE); + + uint32_t bit; + ecma_internal_property_id_t mask_prop_id; + + if (index >= 32) + { + mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63; + bit = (uint32_t) 1u << (index - 32); + } + else + { + mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31; + bit = (uint32_t) 1u << index; + } + + ecma_property_t *mask_prop_p = ecma_find_internal_property (obj_p, mask_prop_id); + if (mask_prop_p == NULL) + { + mask_prop_p = ecma_create_internal_property (obj_p, mask_prop_id); + mask_prop_p->u.internal_property.value = 0; + } + + uint32_t bit_mask = mask_prop_p->u.internal_property.value; + + if (bit_mask & bit) + { + return NULL; + } + + bit_mask |= bit; + + mask_prop_p->u.internal_property.value = bit_mask; + + ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); + ecma_property_writable_value_t writable; + ecma_property_enumerable_value_t enumerable; + ecma_property_configurable_value_t configurable; + + switch (id) + { +#define ROUTINE(name, c_function_name, args_number, length_prop_value) case name: \ + { \ + ecma_object_t *func_obj_p = ecma_builtin_make_function_object_for_routine (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, \ + id, \ + length_prop_value); \ + \ + writable = ECMA_PROPERTY_WRITABLE; \ + enumerable = ECMA_PROPERTY_NOT_ENUMERABLE; \ + configurable = ECMA_PROPERTY_CONFIGURABLE; \ + \ + value = ecma_make_object_value (func_obj_p); \ + \ + break; \ + } +#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) case name: \ + { \ + value = ecma_make_object_value (obj_getter); \ + writable = prop_writable; \ + enumerable = prop_enumerable; \ + configurable = prop_configurable; \ + break; \ + } +#include "ecma-builtin-boolean-prototype.inc.h" + + default: + { + JERRY_UNREACHABLE (); + } + } + + ecma_property_t *prop_p = ecma_create_named_data_property (obj_p, + prop_name_p, + writable, + enumerable, + configurable); + + prop_p->u.named_data_property.value = ecma_copy_value (value, false); + ecma_gc_update_may_ref_younger_object_flag_by_value (obj_p, + prop_p->u.named_data_property.value); + + ecma_free_value (value, true); + + return prop_p; +} /* ecma_builtin_boolean_prototype_try_to_instantiate_property */ /** - * Boolean of the Boolean.prototype object's built-in properties + * Dispatcher of the Boolean.prototype object's built-in routines + * + * @return completion-value + * Returned value must be freed with ecma_free_completion_value. */ -static const ecma_length_t ecma_builtin_boolean_prototype_property_number = (sizeof (ecma_builtin_property_names) / - sizeof (ecma_magic_string_id_t)); +ecma_completion_value_t +ecma_builtin_boolean_prototype_dispatch_routine (ecma_magic_string_id_t builtin_routine_id, /**< Boolean.prototype + object's built-in + routine's name */ + ecma_value_t this_arg_value __unused, /**< 'this' argument value */ + ecma_value_t arguments_list [] __unused, /**< list of arguments + passed to routine */ + ecma_length_t arguments_number __unused) /**< length of + arguments' list */ +{ + switch (builtin_routine_id) + { +#define ROUTINE_ARG(n) (arguments_number >= n ? arguments_list[n - 1] : value_undefined) +#define ROUTINE_ARG_LIST_0 +#define ROUTINE_ARG_LIST_1 , ROUTINE_ARG(1) +#define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1, ROUTINE_ARG(2) +#define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2, ROUTINE_ARG(3) +#define ROUTINE_ARG_LIST_NON_FIXED , arguments_list, arguments_number +#define ROUTINE(name, c_function_name, args_number, length_prop_value) \ + case name: \ + { \ + return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \ + } +#include "ecma-builtin-boolean-prototype.inc.h" +#undef ROUTINE_ARG_LIST_0 +#undef ROUTINE_ARG_LIST_1 +#undef ROUTINE_ARG_LIST_2 +#undef ROUTINE_ARG_LIST_3 +#undef ROUTINE_ARG_LIST_NON_FIXED + + default: + { + JERRY_UNREACHABLE (); + } + } +} /* ecma_builtin_boolean_prototype_dispatch_routine */ /** * The Boolean.prototype object's 'toString' routine @@ -164,177 +293,6 @@ ecma_builtin_boolean_prototype_object_value_of (ecma_value_t this) /**< this arg return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } /* ecma_builtin_boolean_prototype_object_value_of */ -/** - * If the property's name is one of built-in properties of the Boolean.prototype object - * that is not instantiated yet, instantiate the property and - * return pointer to the instantiated property. - * - * @return pointer property, if one was instantiated, - * NULL - otherwise. - */ -ecma_property_t* -ecma_builtin_boolean_prototype_try_to_instantiate_property (ecma_object_t *obj_p, /**< object */ - ecma_string_t *prop_name_p) /**< property's name */ -{ - JERRY_ASSERT (ecma_builtin_is (obj_p, ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE)); - JERRY_ASSERT (ecma_find_named_property (obj_p, prop_name_p) == NULL); - - ecma_magic_string_id_t id; - - if (!ecma_is_string_magic (prop_name_p, &id)) - { - return NULL; - } - - int32_t index = ecma_builtin_bin_search_for_magic_string_id_in_array (ecma_builtin_property_names, - ecma_builtin_boolean_prototype_property_number, - id); - - if (index == -1) - { - return NULL; - } - - JERRY_ASSERT (index >= 0 && (uint32_t) index < sizeof (uint64_t) * JERRY_BITSINBYTE); - - uint32_t bit; - ecma_internal_property_id_t mask_prop_id; - - if (index >= 32) - { - mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_32_63; - bit = (uint32_t) 1u << (index - 32); - } - else - { - mask_prop_id = ECMA_INTERNAL_PROPERTY_NON_INSTANTIATED_BUILT_IN_MASK_0_31; - bit = (uint32_t) 1u << index; - } - - ecma_property_t *mask_prop_p = ecma_find_internal_property (obj_p, mask_prop_id); - if (mask_prop_p == NULL) - { - mask_prop_p = ecma_create_internal_property (obj_p, mask_prop_id); - mask_prop_p->u.internal_property.value = 0; - } - - uint32_t bit_mask = mask_prop_p->u.internal_property.value; - - if (bit_mask & bit) - { - return NULL; - } - - bit_mask |= bit; - - mask_prop_p->u.internal_property.value = bit_mask; - - ecma_value_t value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); - ecma_property_writable_value_t writable = ECMA_PROPERTY_WRITABLE; - ecma_property_enumerable_value_t enumerable = ECMA_PROPERTY_NOT_ENUMERABLE; - ecma_property_configurable_value_t configurable = ECMA_PROPERTY_CONFIGURABLE; - - switch (id) - { -#define CASE_ROUTINE_PROP_LIST(name, c_function_name, args_number, length) case name: \ - { \ - ecma_object_t *func_obj_p = ecma_builtin_make_function_object_for_routine (ECMA_BUILTIN_ID_BOOLEAN_PROTOTYPE, \ - id, \ - length); \ - \ - value = ecma_make_object_value (func_obj_p); \ - \ - break; \ - } - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_ROUTINES_PROPERTY_LIST (CASE_ROUTINE_PROP_LIST) -#undef CASE_ROUTINE_PROP_LIST -#define CASE_VALUE_PROP_LIST(name, value) case name: - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_OBJECT_VALUES_PROPERTY_LIST (CASE_VALUE_PROP_LIST) -#undef CASE_VALUE_PROP_LIST - { - writable = ECMA_PROPERTY_NOT_WRITABLE; - enumerable = ECMA_PROPERTY_NOT_ENUMERABLE; - configurable = ECMA_PROPERTY_NOT_CONFIGURABLE; - - switch (id) - { -#define CASE_OBJECT_VALUE_PROP_LIST(name, value_obj) case name: { value = ecma_make_object_value (value_obj); break; } - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_OBJECT_VALUES_PROPERTY_LIST (CASE_OBJECT_VALUE_PROP_LIST) -#undef CASE_OBJECT_VALUE_PROP_LIST - default: - { - JERRY_UNREACHABLE (); - } - } - - break; - } - - default: - { - JERRY_UNREACHABLE (); - } - } - - ecma_property_t *prop_p = ecma_create_named_data_property (obj_p, - prop_name_p, - writable, - enumerable, - configurable); - - prop_p->u.named_data_property.value = ecma_copy_value (value, false); - ecma_gc_update_may_ref_younger_object_flag_by_value (obj_p, - prop_p->u.named_data_property.value); - - ecma_free_value (value, true); - - return prop_p; -} /* ecma_builtin_boolean_prototype_try_to_instantiate_property */ - -/** - * Dispatcher of the Boolean.prototype object's built-in routines - * - * @return completion-value - * Returned value must be freed with ecma_free_completion_value. - */ -ecma_completion_value_t -ecma_builtin_boolean_prototype_dispatch_routine (ecma_magic_string_id_t builtin_routine_id, /**< Boolean.prototype - object's built-in - routine's name */ - ecma_value_t this_arg_value __unused, /**< 'this' argument value */ - ecma_value_t arguments_list [] __unused, /**< list of arguments - passed to routine */ - ecma_length_t arguments_number __unused) /**< length of - arguments' list */ -{ - switch (builtin_routine_id) - { -#define ROUTINE_ARG(n) (arguments_number >= n ? arguments_list[n - 1] : value_undefined) -#define ROUTINE_ARG_LIST_0 -#define ROUTINE_ARG_LIST_1 , ROUTINE_ARG(1) -#define ROUTINE_ARG_LIST_2 ROUTINE_ARG_LIST_1, ROUTINE_ARG(2) -#define ROUTINE_ARG_LIST_3 ROUTINE_ARG_LIST_2, ROUTINE_ARG(3) -#define ROUTINE_ARG_LIST_NON_FIXED , arguments_list, arguments_number -#define CASE_ROUTINE_PROP_LIST(name, c_function_name, args_number, length) \ - case name: \ - { \ - return c_function_name (this_arg_value ROUTINE_ARG_LIST_ ## args_number); \ - } - ECMA_BUILTIN_BOOLEAN_PROTOTYPE_OBJECT_ROUTINES_PROPERTY_LIST (CASE_ROUTINE_PROP_LIST) -#undef CASE_ROUTINE_PROP_LIST -#undef ROUTINE_ARG_LIST_0 -#undef ROUTINE_ARG_LIST_1 -#undef ROUTINE_ARG_LIST_2 -#undef ROUTINE_ARG_LIST_3 -#undef ROUTINE_ARG_LIST_NON_FIXED - - default: - { - JERRY_UNREACHABLE (); - } - } -} /* ecma_builtin_boolean_prototype_dispatch_routine */ - /** * @} * @} diff --git a/src/libecmabuiltins/ecma-builtin-boolean-prototype.inc.h b/src/libecmabuiltins/ecma-builtin-boolean-prototype.inc.h new file mode 100644 index 000000000..c7160d100 --- /dev/null +++ b/src/libecmabuiltins/ecma-builtin-boolean-prototype.inc.h @@ -0,0 +1,42 @@ +/* Copyright 2014 Samsung Electronics Co., Ltd. + * + * 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. + */ + +/* + * Boolean.prototype description + */ + +#ifndef OBJECT_VALUE +# define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) +#endif /* !OBJECT_VALUE */ + +#ifndef ROUTINE +# define ROUTINE(name, c_function_name, args_number, length_prop_value) +#endif /* !ROUTINE */ + +/* Object properties: + * (property name, object pointer getter) */ +OBJECT_VALUE (ECMA_MAGIC_STRING_CONSTRUCTOR, + ecma_builtin_get (ECMA_BUILTIN_ID_BOOLEAN), + ECMA_PROPERTY_WRITABLE, + ECMA_PROPERTY_NOT_ENUMERABLE, + ECMA_PROPERTY_CONFIGURABLE) + +/* Routine properties: + * (property name, C routine name, arguments number or NON_FIXED, value of the routine's length property) */ +ROUTINE (ECMA_MAGIC_STRING_TO_STRING_UL, ecma_builtin_boolean_prototype_object_to_string, 0, 0) +ROUTINE (ECMA_MAGIC_STRING_VALUE_OF_UL, ecma_builtin_boolean_prototype_object_value_of, 0, 0) + +#undef OBJECT_VALUE +#undef ROUTINE