Skip to content

Refactor ECMA builtin template #905

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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
Expand All @@ -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)
{
Expand Down Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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
9 changes: 2 additions & 7 deletions jerry-core/ecma/builtin-objects/ecma-builtins-internal.h
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -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, \
Expand All @@ -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 */
55 changes: 0 additions & 55 deletions jerry-core/ecma/builtin-objects/ecma-builtins.c
Original file line number Diff line number Diff line change
Expand Up @@ -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) \
Expand Down Expand Up @@ -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 */

/**
* @}
* @}
Expand Down
4 changes: 2 additions & 2 deletions jerry-core/ecma/builtin-objects/ecma-builtins.inc.h
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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,
Expand Down