/** * Get value field of ecma value * * @return value field */ static uintptr_t __attr_pure___ ecma_get_value_value_field (ecma_value_t value) /**< ecma value */ { return (uintptr_t) jrt_extract_bit_field (value, ECMA_VALUE_VALUE_POS, ECMA_VALUE_VALUE_WIDTH); } /* ecma_get_value_value_field */
/** * Get GC reference counter of the object. */ static uint32_t ecma_gc_get_object_refs (ecma_object_t *object_p) /**< object */ { JERRY_ASSERT (object_p != NULL); return (uint32_t) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_GC_REFS_POS, ECMA_OBJECT_GC_REFS_WIDTH); } /* ecma_gc_get_object_refs */
/** * Get visited flag of the object. */ static bool ecma_gc_is_object_visited (ecma_object_t *object_p) /**< object */ { JERRY_ASSERT (object_p != NULL); bool flag_value = (bool) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_GC_VISITED_POS, ECMA_OBJECT_GC_VISITED_WIDTH); return (flag_value != ecma_gc_visited_flip_flag); } /* ecma_gc_is_object_visited */
/** * Get next object in list of objects with same generation. */ static ecma_object_t* ecma_gc_get_object_next (ecma_object_t *object_p) /**< object */ { JERRY_ASSERT (object_p != NULL); JERRY_ASSERT (sizeof (uintptr_t) * JERRY_BITSINBYTE >= ECMA_OBJECT_GC_NEXT_CP_WIDTH); uintptr_t next_cp = (uintptr_t) jrt_extract_bit_field (object_p->container, ECMA_OBJECT_GC_NEXT_CP_POS, ECMA_OBJECT_GC_NEXT_CP_WIDTH); return ECMA_GET_POINTER (ecma_object_t, next_cp); } /* ecma_gc_get_object_next */
/** * Handle calling [[Call]] of built-in object * * @return ecma value */ ecma_value_t ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_value_t this_arg_value, /**< 'this' argument value */ const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< arguments list length */ { JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_value_t ret_value = ecma_make_simple_value (ECMA_SIMPLE_VALUE_EMPTY); if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); uint64_t builtin_routine_desc = desc_prop_p->u.internal_property.value; uint64_t built_in_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH); JERRY_ASSERT (built_in_id_field < ECMA_BUILTIN_ID__COUNT); uint64_t routine_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); JERRY_ASSERT ((uint16_t) routine_id_field == routine_id_field); ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field; uint16_t routine_id = (uint16_t) routine_id_field; ret_value = ecma_builtin_dispatch_routine (built_in_id, routine_id, this_arg_value, arguments_list_p, arguments_list_len); } else { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); switch (builtin_id) { #define BUILTIN(builtin_id, \ object_type, \ object_prototype_builtin_id, \ is_extensible, \ is_static, \ lowercase_name) \ case builtin_id: \ { \ if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \ { \ ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \ arguments_list_len); \ } \ break; \ } #include "ecma-builtins.inc.h" case ECMA_BUILTIN_ID__COUNT: { JERRY_UNREACHABLE (); } default: { #ifdef CONFIG_ECMA_COMPACT_PROFILE JERRY_UNREACHABLE (); #else /* CONFIG_ECMA_COMPACT_PROFILE */ JERRY_UNIMPLEMENTED ("The built-in is not implemented."); #endif /* !CONFIG_ECMA_COMPACT_PROFILE */ } } } JERRY_ASSERT (!ecma_is_value_empty (ret_value)); return ret_value; } /* ecma_builtin_dispatch_call */
/** * If the property's name is one of built-in properties of the 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_try_to_instantiate_property (ecma_object_t *object_p, /**< object */ ecma_string_t *string_p) /**< property's name */ { JERRY_ASSERT (ecma_get_object_is_builtin (object_p)); const ecma_object_type_t type = ecma_get_object_type (object_p); if (type == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_string_t *magic_string_length_p = ecma_get_magic_string (LIT_MAGIC_STRING_LENGTH); bool is_length_property = ecma_compare_ecma_strings (string_p, magic_string_length_p); ecma_deref_ecma_string (magic_string_length_p); if (is_length_property) { /* * Lazy instantiation of 'length' property * * Note: * We don't need to mark that the property was already lazy instantiated, * as it is non-configurable and so can't be deleted */ ecma_property_t *desc_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); uint64_t builtin_routine_desc = desc_prop_p->u.internal_property.value; JERRY_STATIC_ASSERT (sizeof (uint8_t) * JERRY_BITSINBYTE == ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH, bits_in_uint8_t_must_be_equal_to_ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); uint8_t length_prop_value = (uint8_t) jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_POS, ECMA_BUILTIN_ROUTINE_ID_LENGTH_VALUE_WIDTH); ecma_property_t *len_prop_p = ecma_create_named_data_property (object_p, string_p, false, false, false); ecma_number_t *len_p = ecma_alloc_number (); *len_p = length_prop_value; ecma_set_named_data_property_value (len_prop_p, ecma_make_number_value (len_p)); JERRY_ASSERT (!ecma_is_property_configurable (len_prop_p)); return len_prop_p; } return NULL; } else { ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (object_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; JERRY_ASSERT (ecma_builtin_is (object_p, builtin_id)); switch (builtin_id) { #define BUILTIN(builtin_id, \ object_type, \ object_prototype_builtin_id, \ is_extensible, \ is_static, \ lowercase_name) \ case builtin_id: \ { \ return ecma_builtin_ ## lowercase_name ## _try_to_instantiate_property (object_p, \ string_p); \ } #include "ecma-builtins.inc.h" case ECMA_BUILTIN_ID__COUNT: { JERRY_UNREACHABLE (); } default: { #ifdef CONFIG_ECMA_COMPACT_PROFILE JERRY_UNREACHABLE (); #else /* CONFIG_ECMA_COMPACT_PROFILE */ JERRY_UNIMPLEMENTED ("The built-in is not implemented."); #endif /* !CONFIG_ECMA_COMPACT_PROFILE */ } } JERRY_UNREACHABLE (); } } /* ecma_builtin_try_to_instantiate_property */
/** * Handle calling [[Call]] of built-in object * * @return completion-value */ ecma_completion_value_t ecma_builtin_dispatch_call (ecma_object_t *obj_p, /**< built-in object */ ecma_value_t this_arg_value, /**< 'this' argument value */ ecma_collection_header_t* arg_collection_p) /**< arguments collection */ { JERRY_ASSERT (ecma_get_object_is_builtin (obj_p)); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); const ecma_length_t arguments_list_len = arg_collection_p != NULL ? arg_collection_p->unit_number : 0; MEM_DEFINE_LOCAL_ARRAY (arguments_list_p, arguments_list_len, ecma_value_t); ecma_collection_iterator_t arg_collection_iter; ecma_collection_iterator_init (&arg_collection_iter, arg_collection_p); for (ecma_length_t arg_index = 0; ecma_collection_iterator_next (&arg_collection_iter); arg_index++) { arguments_list_p[arg_index] = *arg_collection_iter.current_value_p; } if (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_BUILT_IN_FUNCTION) { ecma_property_t *desc_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ROUTINE_DESC); uint64_t builtin_routine_desc = desc_prop_p->u.internal_property.value; uint64_t built_in_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_OBJECT_ID_WIDTH); JERRY_ASSERT (built_in_id_field < ECMA_BUILTIN_ID__COUNT); uint64_t routine_id_field = jrt_extract_bit_field (builtin_routine_desc, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_POS, ECMA_BUILTIN_ROUTINE_ID_BUILT_IN_ROUTINE_ID_WIDTH); JERRY_ASSERT ((uint16_t) routine_id_field == routine_id_field); ecma_builtin_id_t built_in_id = (ecma_builtin_id_t) built_in_id_field; uint16_t routine_id = (uint16_t) routine_id_field; ret_value = ecma_builtin_dispatch_routine (built_in_id, routine_id, this_arg_value, arguments_list_p, arguments_list_len); } else { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_FUNCTION); ecma_property_t *built_in_id_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_BUILT_IN_ID); ecma_builtin_id_t builtin_id = (ecma_builtin_id_t) built_in_id_prop_p->u.internal_property.value; JERRY_ASSERT (ecma_builtin_is (obj_p, builtin_id)); switch (builtin_id) { #define BUILTIN(builtin_id, \ object_type, \ object_prototype_builtin_id, \ is_extensible, \ is_static, \ lowercase_name) \ case builtin_id: \ { \ if (object_type == ECMA_OBJECT_TYPE_FUNCTION) \ { \ ret_value = ecma_builtin_ ## lowercase_name ## _dispatch_call (arguments_list_p, \ arguments_list_len); \ } \ break; \ } #include "ecma-builtins.inc.h" case ECMA_BUILTIN_ID__COUNT: { JERRY_UNREACHABLE (); } default: { #ifdef CONFIG_ECMA_COMPACT_PROFILE JERRY_UNREACHABLE (); #else /* CONFIG_ECMA_COMPACT_PROFILE */ JERRY_UNIMPLEMENTED ("The built-in is not implemented."); #endif /* !CONFIG_ECMA_COMPACT_PROFILE */ } } } MEM_FINALIZE_LOCAL_ARRAY (arguments_list_p); JERRY_ASSERT (!ecma_is_completion_value_empty (ret_value)); return ret_value; } /* ecma_builtin_dispatch_call */