/** * Handle calling [[Call]] of built-in String object * * See also: * ECMA-262 v6, 21.1.1.1 * * @return ecma value */ ecma_value_t ecma_builtin_string_dispatch_call (const ecma_value_t *arguments_list_p, /**< arguments list */ ecma_length_t arguments_list_len) /**< number of arguments */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); ecma_value_t ret_value = ECMA_VALUE_EMPTY; /* 1. */ if (arguments_list_len == 0) { ret_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); } #if ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) /* 2.a */ else if (ecma_is_value_symbol (arguments_list_p[0])) { ret_value = ecma_get_symbol_descriptive_string (arguments_list_p[0]); } #endif /* ENABLED (JERRY_ES2015_BUILTIN_SYMBOL) */ /* 2.b */ else { ret_value = ecma_op_to_string (arguments_list_p[0]); } return ret_value; } /* ecma_builtin_string_dispatch_call */
/** * The String object's 'fromCharCode' routine * * See also: * ECMA-262 v5, 15.5.3.2 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_string_object_from_char_code (ecma_value_t this_arg, /**< 'this' argument */ const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { JERRY_UNUSED (this_arg); if (args_number == 0) { return ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); } ecma_value_t ret_value = ECMA_VALUE_EMPTY; ecma_string_t *ret_string_p = NULL; lit_utf8_size_t utf8_buf_size = args_number * LIT_CESU8_MAX_BYTES_IN_CODE_UNIT; JMEM_DEFINE_LOCAL_ARRAY (utf8_buf_p, utf8_buf_size, lit_utf8_byte_t); lit_utf8_size_t utf8_buf_used = 0; for (ecma_length_t arg_index = 0; arg_index < args_number && ecma_is_value_empty (ret_value); arg_index++) { ECMA_OP_TO_NUMBER_TRY_CATCH (arg_num, args[arg_index], ret_value); uint32_t uint32_char_code = ecma_number_to_uint32 (arg_num); ecma_char_t code_unit = (uint16_t) uint32_char_code; JERRY_ASSERT (utf8_buf_used <= utf8_buf_size - LIT_UTF8_MAX_BYTES_IN_CODE_UNIT); utf8_buf_used += lit_code_unit_to_utf8 (code_unit, utf8_buf_p + utf8_buf_used); JERRY_ASSERT (utf8_buf_used <= utf8_buf_size); ECMA_OP_TO_NUMBER_FINALIZE (arg_num); } if (ecma_is_value_empty (ret_value)) { ret_string_p = ecma_new_ecma_string_from_utf8 (utf8_buf_p, utf8_buf_used); } JMEM_FINALIZE_LOCAL_ARRAY (utf8_buf_p); if (ecma_is_value_empty (ret_value)) { ret_value = ecma_make_string_value (ret_string_p); } return ret_value; } /* ecma_builtin_string_object_from_char_code */
/** * The Function.prototype object's 'toString' routine * * See also: * ECMA-262 v5, 15.3.4.2 * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */ { ecma_value_t ret_value = ECMA_VALUE_EMPTY; 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 */
/** * List names of a String object's lazy instantiated properties * * @return string values collection */ void ecma_op_string_list_lazy_property_names (ecma_object_t *obj_p, /**< a String 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 */ { JERRY_ASSERT (ecma_get_object_type (obj_p) == ECMA_OBJECT_TYPE_CLASS); ecma_collection_header_t *for_enumerable_p = main_collection_p; ecma_collection_header_t *for_non_enumerable_p = separate_enumerable ? non_enum_collection_p : main_collection_p; ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) obj_p; JERRY_ASSERT (ext_object_p->u.class_prop.class_id == LIT_MAGIC_STRING_STRING_UL); ecma_string_t *prim_value_str_p = ecma_get_string_from_value (ext_object_p->u.class_prop.u.value); ecma_length_t length = ecma_string_get_length (prim_value_str_p); for (ecma_length_t i = 0; i < length; i++) { ecma_string_t *name_p = ecma_new_ecma_string_from_uint32 (i); /* the properties are enumerable (ECMA-262 v5, 15.5.5.2.9) */ ecma_append_to_values_collection (for_enumerable_p, ecma_make_string_value (name_p), 0); ecma_deref_ecma_string (name_p); } ecma_append_to_values_collection (for_non_enumerable_p, ecma_make_magic_string_value (LIT_MAGIC_STRING_LENGTH), 0); } /* ecma_op_string_list_lazy_property_names */
/** * String object creation operation. * * See also: ECMA-262 v5, 15.5.2.1 * * @return ecma value * Returned value must be freed with ecma_free_value */ ecma_value_t ecma_op_create_string_object (const ecma_value_t *arguments_list_p, /**< list of arguments that are passed to String constructor */ ecma_length_t arguments_list_len) /**< length of the arguments' list */ { JERRY_ASSERT (arguments_list_len == 0 || arguments_list_p != NULL); ecma_value_t prim_value = ecma_make_magic_string_value (LIT_MAGIC_STRING__EMPTY); if (arguments_list_len > 0) { prim_value = ecma_op_to_string (arguments_list_p[0]); if (ECMA_IS_VALUE_ERROR (prim_value)) { return prim_value; } JERRY_ASSERT (ecma_is_value_string (prim_value)); } #ifndef CONFIG_DISABLE_STRING_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_STRING_PROTOTYPE); #else /* CONFIG_DISABLE_STRING_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* !CONFIG_DISABLE_STRING_BUILTIN */ ecma_object_t *object_p = ecma_create_object (prototype_obj_p, sizeof (ecma_extended_object_t), ECMA_OBJECT_TYPE_CLASS); ecma_deref_object (prototype_obj_p); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; ext_object_p->u.class_prop.class_id = LIT_MAGIC_STRING_STRING_UL; ext_object_p->u.class_prop.u.value = prim_value; return ecma_make_object_value (object_p); } /* ecma_op_create_string_object */
/** * Dispatcher of the built-in's routines * * @return ecma value * Returned value must be freed with ecma_free_value. */ ecma_value_t ecma_builtin_date_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[], /**< list of arguments * passed to routine */ ecma_length_t arguments_number) /**< length of arguments' list */ { if (JERRY_UNLIKELY (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_JSON)) { return ecma_builtin_date_prototype_to_json (this_arg); } if (!ecma_is_value_object (this_arg) || !ecma_object_class_is (ecma_get_object_from_value (this_arg), LIT_MAGIC_STRING_DATE_UL)) { return ecma_raise_type_error (ECMA_ERR_MSG ("Date object expected")); } ecma_object_t *object_p = ecma_get_object_from_value (this_arg); ecma_extended_object_t *ext_object_p = (ecma_extended_object_t *) object_p; ecma_number_t *prim_value_p = ECMA_GET_INTERNAL_VALUE_POINTER (ecma_number_t, ext_object_p->u.class_prop.u.value); if (builtin_routine_id == ECMA_DATE_PROTOTYPE_GET_TIME) { return ecma_make_number_value (*prim_value_p); } if (builtin_routine_id == ECMA_DATE_PROTOTYPE_SET_TIME) { ecma_value_t time = (arguments_number >= 1 ? arguments_list[0] : ECMA_VALUE_UNDEFINED); ecma_value_t ret_value = ECMA_VALUE_EMPTY; /* 1. */ ECMA_OP_TO_NUMBER_TRY_CATCH (time_num, time, ret_value); *prim_value_p = ecma_date_time_clip (time_num); ret_value = ecma_make_number_value (time_num); ECMA_OP_TO_NUMBER_FINALIZE (time_num); return ret_value; } if (builtin_routine_id <= ECMA_DATE_PROTOTYPE_SET_UTC_MILLISECONDS) { ecma_number_t this_num = *prim_value_p; if (!BUILTIN_DATE_FUNCTION_IS_UTC (builtin_routine_id)) { this_num += ecma_date_local_time_zone (this_num); } if (builtin_routine_id <= ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET) { return ecma_builtin_date_prototype_dispatch_get (builtin_routine_id, this_num); } return ecma_builtin_date_prototype_dispatch_set (builtin_routine_id, ext_object_p, this_num, arguments_list, arguments_number); } if (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_ISO_STRING) { if (ecma_number_is_nan (*prim_value_p) || ecma_number_is_infinity (*prim_value_p)) { return ecma_raise_range_error (ECMA_ERR_MSG ("Date must be a finite number.")); } return ecma_date_value_to_iso_string (*prim_value_p); } if (ecma_number_is_nan (*prim_value_p)) { return ecma_make_magic_string_value (LIT_MAGIC_STRING_INVALID_DATE_UL); } switch (builtin_routine_id) { case ECMA_DATE_PROTOTYPE_TO_STRING: { return ecma_date_value_to_string (*prim_value_p); } case ECMA_DATE_PROTOTYPE_TO_DATE_STRING: { return ecma_date_value_to_date_string (*prim_value_p); } case ECMA_DATE_PROTOTYPE_TO_TIME_STRING: { return ecma_date_value_to_time_string (*prim_value_p); } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_TO_UTC_STRING); return ecma_date_value_to_utc_string (*prim_value_p); } } } /* ecma_builtin_date_prototype_dispatch_routine */
/** * Dispatch get date functions * * @return ecma value * Returned value must be freed with ecma_free_value. */ static ecma_value_t ecma_builtin_date_prototype_dispatch_get (uint16_t builtin_routine_id, /**< built-in wide routine * identifier */ ecma_number_t date_num) /**< date converted to number */ { if (ecma_number_is_nan (date_num)) { return ecma_make_magic_string_value (LIT_MAGIC_STRING_NAN); } switch (builtin_routine_id) { case ECMA_DATE_PROTOTYPE_GET_FULL_YEAR: case ECMA_DATE_PROTOTYPE_GET_UTC_FULL_YEAR: #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN case ECMA_DATE_PROTOTYPE_GET_YEAR: #endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */ { date_num = ecma_date_year_from_time (date_num); #ifndef CONFIG_DISABLE_ANNEXB_BUILTIN if (builtin_routine_id == ECMA_DATE_PROTOTYPE_GET_YEAR) { date_num -= 1900; } #endif /* !CONFIG_DISABLE_ANNEXB_BUILTIN */ break; } case ECMA_DATE_PROTOTYPE_GET_MONTH: case ECMA_DATE_PROTOTYPE_GET_UTC_MONTH: { date_num = ecma_date_month_from_time (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_DATE: case ECMA_DATE_PROTOTYPE_GET_UTC_DATE: { date_num = ecma_date_date_from_time (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_DAY: case ECMA_DATE_PROTOTYPE_GET_UTC_DAY: { date_num = ecma_date_week_day (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_HOURS: case ECMA_DATE_PROTOTYPE_GET_UTC_HOURS: { date_num = ecma_date_hour_from_time (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_MINUTES: case ECMA_DATE_PROTOTYPE_GET_UTC_MINUTES: { date_num = ecma_date_min_from_time (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_SECONDS: case ECMA_DATE_PROTOTYPE_GET_UTC_SECONDS: { date_num = ecma_date_sec_from_time (date_num); break; } case ECMA_DATE_PROTOTYPE_GET_MILLISECONDS: case ECMA_DATE_PROTOTYPE_GET_UTC_MILLISECONDS: { date_num = ecma_date_ms_from_time (date_num); break; } default: { JERRY_ASSERT (builtin_routine_id == ECMA_DATE_PROTOTYPE_GET_UTC_TIMEZONE_OFFSET); date_num = ecma_date_timezone_offset (date_num); break; } } return ecma_make_number_value (date_num); } /* ecma_builtin_date_prototype_dispatch_get */