diff --git a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h index 9fc1f8a21c..0a8d003e5d 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtin-internal-routines-template.inc.h @@ -1,4 +1,5 @@ -/* Copyright 2014-2015 Samsung Electronics Co., Ltd. +/* Copyright 2014-2016 Samsung Electronics Co., Ltd. + * Copyright 2016 University of Szeged * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -27,14 +28,14 @@ #define PASTE_(x, y) PASTE__ (x, y) #define PASTE(x, y) PASTE_ (x, y) -#define SORT_PROPERTY_NAMES_ROUTINE_NAME(builtin_underscored_id) \ - PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _sort_property_names) -#define TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME(builtin_underscored_id) \ - PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _try_to_instantiate_property) -#define LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME(builtin_underscored_id) \ - PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _list_lazy_property_names) -#define DISPATCH_ROUTINE_ROUTINE_NAME(builtin_underscored_id) \ - PASTE (PASTE (ecma_builtin_, builtin_underscored_id), _dispatch_routine) +#define FIND_PROPERTY_INDEX_ROUTINE_NAME \ + PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _find_property_index) +#define TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME \ + PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _try_to_instantiate_property) +#define LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME \ + PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _list_lazy_property_names) +#define DISPATCH_ROUTINE_ROUTINE_NAME \ + PASTE (PASTE (ecma_builtin_, BUILTIN_UNDERSCORED_ID), _dispatch_routine) #define ROUTINE_ARG(n) , ecma_value_t arg ## n #define ROUTINE_ARG_LIST_0 ecma_value_t this_arg @@ -56,7 +57,7 @@ #define ECMA_BUILTIN_PROPERTY_NAMES \ PASTE (PASTE (ecma_builtin_property_names, _), BUILTIN_UNDERSCORED_ID) -static lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] = +static const lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] = { #define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) name, #define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) name, @@ -67,34 +68,79 @@ static lit_magic_string_id_t ECMA_BUILTIN_PROPERTY_NAMES[] = #include BUILTIN_INC_HEADER_NAME }; +#define ECMA_BUILTIN_PROPERTY_NAME_INDEX(name) \ + PASTE (PASTE (PASTE (PASTE (ecma_builtin_property_names, _), BUILTIN_UNDERSCORED_ID), _), name) + +enum +{ +#define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#define STRING_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#define CP_UNIMPLEMENTED_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#define ROUTINE(name, c_function_name, args_number, length_prop_value) \ + ECMA_BUILTIN_PROPERTY_NAME_INDEX(name), +#include BUILTIN_INC_HEADER_NAME +}; + /** - * Sort builtin's property names array + * Return the index of a magic string ID in the ECMA_BUILTIN_PROPERTY_NAMES + * array, or -1 if not found. + * + * Note: we trust the compiler to find the optimal (most performance and/or + * memory effective) way of implementing the switch construct of this function + * in binary code (e.g., jump tables for large consecutive cases, binary search + * for non-consecutive cases, some simple conditional branches for low number of + * cases, etc. -- the worst case is a linear sequence of comparisons, but even + * that's not that bad, since we cannot have more than 64 IDs in the array). */ -void -SORT_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (void) +static int32_t +FIND_PROPERTY_INDEX_ROUTINE_NAME (lit_magic_string_id_t id) /**< magic string id */ { - bool swapped; - - do + switch (id) { - swapped = false; - - for (ecma_length_t i = 1; - i < (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) / sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0])); - i++) +#define SIMPLE_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#define NUMBER_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#define STRING_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#define CP_UNIMPLEMENTED_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#define OBJECT_VALUE(name, obj_getter, prop_writable, prop_enumerable, prop_configurable) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#define ROUTINE(name, c_function_name, args_number, length_prop_value) \ + case name: \ + { \ + return ECMA_BUILTIN_PROPERTY_NAME_INDEX(name); \ + } +#include BUILTIN_INC_HEADER_NAME + default: { - if (ECMA_BUILTIN_PROPERTY_NAMES[i] < ECMA_BUILTIN_PROPERTY_NAMES[i - 1]) - { - lit_magic_string_id_t id_temp = ECMA_BUILTIN_PROPERTY_NAMES[i - 1]; - ECMA_BUILTIN_PROPERTY_NAMES[i - 1] = ECMA_BUILTIN_PROPERTY_NAMES[i]; - ECMA_BUILTIN_PROPERTY_NAMES[i] = id_temp; - - swapped = true; - } + return -1; } } - while (swapped); -} /* SORT_PROPERTY_NAMES_ROUTINE_NAME */ +} /* FIND_PROPERTY_INDEX_ROUTINE_NAME */ /** * If the property's name is one of built-in properties of the built-in object @@ -105,8 +151,8 @@ SORT_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (void) * NULL - otherwise. */ ecma_property_t * -TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *obj_p, /**< object */ - ecma_string_t *prop_name_p) /**< property's name */ +TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (ecma_object_t *obj_p, /**< object */ + ecma_string_t *prop_name_p) /**< property's name */ { #define OBJECT_ID(builtin_id) const ecma_builtin_id_t builtin_object_id = builtin_id; #include BUILTIN_INC_HEADER_NAME @@ -121,12 +167,7 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t return NULL; } - const ecma_length_t property_numbers = (ecma_length_t) (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) / - sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0])); - int32_t index; - index = ecma_builtin_bin_search_for_magic_string_id_in_array (ECMA_BUILTIN_PROPERTY_NAMES, - property_numbers, - id); + int32_t index = FIND_PROPERTY_INDEX_ROUTINE_NAME (id); if (index == -1) { @@ -284,21 +325,18 @@ TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t * @return string values collection */ void -LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *object_p, /**< a built-in object */ - /** true - list enumerable properties - * into main collection, - * and non-enumerable to - * collection of 'skipped - * non-enumerable' - * properties, - * false - list all properties into - * main collection. - */ - bool separate_enumerable, - /** 'main' collection */ - ecma_collection_header_t *main_collection_p, - /** skipped 'non-enumerable' collection */ - ecma_collection_header_t *non_enum_collection_p) +LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (ecma_object_t *object_p, /**< a built-in object */ + bool separate_enumerable, /**< true - list enumerable properties + into main collection, + and non-enumerable to + collection of 'skipped + non-enumerable' + properties, + false - list all properties into + main collection. */ + ecma_collection_header_t *main_collection_p, /**< 'main' collection */ + ecma_collection_header_t *non_enum_collection_p) /**< skipped 'non-enumerable' + collection */ { ecma_collection_header_t *for_enumerable_p = main_collection_p; (void) for_enumerable_p; @@ -313,16 +351,11 @@ LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *o const ecma_length_t properties_number = (ecma_length_t) (sizeof (ECMA_BUILTIN_PROPERTY_NAMES) / sizeof (ECMA_BUILTIN_PROPERTY_NAMES[0])); - for (ecma_length_t i = 0; - i < properties_number; - i++) + for (ecma_length_t index = 0; + index < properties_number; + index++) { - lit_magic_string_id_t name = ECMA_BUILTIN_PROPERTY_NAMES[i]; - - int32_t index; - index = ecma_builtin_bin_search_for_magic_string_id_in_array (ECMA_BUILTIN_PROPERTY_NAMES, - properties_number, - name); + lit_magic_string_id_t name = ECMA_BUILTIN_PROPERTY_NAMES[index]; uint32_t bit; ecma_internal_property_id_t mask_prop_id; @@ -398,14 +431,14 @@ LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (ecma_object_t *o * Returned value must be freed with ecma_free_value. */ ecma_value_t -DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (uint16_t builtin_routine_id, /**< built-in wide routine - identifier */ - ecma_value_t this_arg_value, /**< 'this' argument - value */ - const ecma_value_t arguments_list[], /**< list of arguments - passed to routine */ - ecma_length_t arguments_number) /**< length of - arguments' list */ +DISPATCH_ROUTINE_ROUTINE_NAME (uint16_t builtin_routine_id, /**< built-in wide routine + identifier */ + ecma_value_t this_arg_value, /**< 'this' argument + value */ + const ecma_value_t arguments_list[], /**< list of arguments + passed to routine */ + ecma_length_t arguments_number) /**< length of + arguments' list */ { /* the arguments may be unused for some built-ins */ (void) this_arg_value; @@ -444,10 +477,11 @@ DISPATCH_ROUTINE_ROUTINE_NAME (BUILTIN_UNDERSCORED_ID) (uint16_t builtin_routine #undef PASTE__ #undef PASTE_ #undef PASTE -#undef SORT_PROPERTY_NAMES_ROUTINE_NAME -#undef DISPATCH_ROUTINE_ROUTINE_NAME +#undef FIND_PROPERTY_INDEX_ROUTINE_NAME #undef TRY_TO_INSTANTIATE_PROPERTY_ROUTINE_NAME +#undef LIST_LAZY_PROPERTY_NAMES_ROUTINE_NAME +#undef DISPATCH_ROUTINE_ROUTINE_NAME #undef BUILTIN_UNDERSCORED_ID #undef BUILTIN_INC_HEADER_NAME #undef ECMA_BUILTIN_PROPERTY_NAMES - +#undef ECMA_BUILTIN_PROPERTY_NAME_INDEX diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h index 11b4d60df0..2ba9bb022c 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins-internal.h @@ -1,4 +1,4 @@ -/* Copyright 2014-2015 Samsung Electronics Co., Ltd. +/* Copyright 2014-2016 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. @@ -60,9 +60,6 @@ /* ecma-builtins.c */ extern ecma_object_t * ecma_builtin_make_function_object_for_routine (ecma_builtin_id_t, uint16_t, uint8_t); -extern int32_t -ecma_builtin_bin_search_for_magic_string_id_in_array (const lit_magic_string_id_t[], - ecma_length_t, lit_magic_string_id_t); #define BUILTIN(builtin_id, \ object_type, \ @@ -88,9 +85,7 @@ extern void \ ecma_builtin_ ## lowercase_name ## _list_lazy_property_names (ecma_object_t *, \ bool, \ ecma_collection_header_t *, \ - ecma_collection_header_t *); \ -extern void \ -ecma_builtin_ ## lowercase_name ## _sort_property_names (void); + ecma_collection_header_t *); #include "ecma-builtins.inc.h" #endif /* !ECMA_BUILTINS_INTERNAL_H */ diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.c b/jerry-core/ecma/builtin-objects/ecma-builtins.c index 01a3bad5ce..08d2c7e063 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.c +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.c @@ -219,10 +219,6 @@ ecma_instantiate_builtin (ecma_builtin_id_t id) /**< built-in id */ case builtin_id: \ { \ JERRY_ASSERT (ecma_builtin_objects[builtin_id] == NULL); \ - if (is_static) \ - { \ - ecma_builtin_ ## lowercase_name ## _sort_property_names (); \ - } \ \ ecma_object_t *prototype_obj_p; \ if (object_prototype_builtin_id == ECMA_BUILTIN_ID__COUNT) \ @@ -701,57 +697,6 @@ ecma_builtin_dispatch_routine (ecma_builtin_id_t builtin_object_id, /**< built-i JERRY_UNREACHABLE (); } /* ecma_builtin_dispatch_routine */ -/** - * Binary search for magic string identifier in array. - * - * Warning: - * array should be sorted in ascending order - * - * @return index of identifier, if it is contained in array, - * -1 - otherwise. - */ -int32_t -ecma_builtin_bin_search_for_magic_string_id_in_array (const lit_magic_string_id_t ids[], /**< array to search in */ - ecma_length_t array_length, /**< number of elements - in the array */ - lit_magic_string_id_t key) /**< value to search for */ -{ -#ifndef JERRY_NDEBUG - /* For binary search the values should be sorted */ - for (ecma_length_t id_index = 1; - id_index < array_length; - id_index++) - { - JERRY_ASSERT (ids[id_index - 1] < ids[id_index]); - } -#endif /* !JERRY_NDEBUG */ - - int32_t min = 0; - int32_t max = (int32_t) array_length - 1; - - while (min <= max) - { - int32_t mid = (min + max) / 2; - - if (ids[mid] == key) - { - return (int32_t) mid; - } - else if (ids[mid] > key) - { - max = mid - 1; - } - else - { - JERRY_ASSERT (ids[mid] < key); - - min = mid + 1; - } - } - - return -1; -} /* ecma_builtin_bin_search_for_magic_string_id_in_array */ - /** * @} * @} diff --git a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h index 475db04618..1a52e9e869 100644 --- a/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h +++ b/jerry-core/ecma/builtin-objects/ecma-builtins.inc.h @@ -1,4 +1,4 @@ -/* Copyright 2014-2015 Samsung Electronics Co., Ltd. +/* Copyright 2014-2016 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. @@ -14,7 +14,7 @@ */ /* Description of built-in objects - in format (ECMA_BUILTIN_ID_id, object_type, class_magic_string_id, prototype_id, is_extensible, underscored_id) */ + in format (ECMA_BUILTIN_ID_id, object_type, prototype_id, is_extensible, is_static, underscored_id) */ /* The Object.prototype object (15.2.4) */ BUILTIN (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE,