/** * Handle calling [[Construct]] of built-in Object object * * @return completion-value */ ecma_completion_value_t ecma_builtin_object_dispatch_construct (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); if (arguments_list_len == 0) { ecma_object_t *obj_p = ecma_op_create_object_object_noarg (); return ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); } else { ecma_completion_value_t new_obj_value = ecma_op_create_object_object_arg (arguments_list_p[0]); if (!ecma_is_completion_value_normal (new_obj_value)) { return new_obj_value; } else { return ecma_make_normal_completion_value (ecma_get_completion_value_value (new_obj_value)); } } } /* ecma_builtin_object_dispatch_construct */
/** * The Date object's 'UTC' routine * * See also: * ECMA-262 v5, 15.9.4.3 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_utc (ecma_value_t this_arg __attr_unused___, /**< this argument */ const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (args_number < 2) { /* Note: * When the UTC function is called with fewer than two arguments, * the behaviour is implementation-dependent, so just return NaN. */ ecma_number_t *nan_p = ecma_alloc_number (); *nan_p = ecma_number_make_nan (); return ecma_make_normal_completion_value (ecma_make_number_value (nan_p)); } ECMA_TRY_CATCH (time_value, ecma_date_construct_helper (args, args_number), ret_value); ecma_number_t *time_p = ecma_get_number_from_value (time_value); ecma_number_t *time_clip_p = ecma_alloc_number (); *time_clip_p = ecma_date_time_clip (*time_p); ret_value = ecma_make_normal_completion_value (ecma_make_number_value (time_clip_p)); ECMA_FINALIZE (time_value); return ret_value; } /* ecma_builtin_date_utc */
/** * The String.prototype object's 'toString' routine * * See also: * ECMA-262 v5, 15.5.4.2 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */ { if (ecma_is_value_string (this_arg)) { return ecma_make_normal_completion_value (ecma_copy_value (this_arg, true)); } else if (ecma_is_value_object (this_arg)) { ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); if (ecma_object_get_class_name (obj_p) == LIT_MAGIC_STRING_STRING_UL) { ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_STRING_VALUE); ecma_string_t *prim_value_str_p = ECMA_GET_NON_NULL_POINTER (ecma_string_t, prim_value_prop_p->u.internal_property.value); prim_value_str_p = ecma_copy_or_ref_ecma_string (prim_value_str_p); return ecma_make_normal_completion_value (ecma_make_string_value (prim_value_str_p)); } } return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } /* ecma_builtin_string_prototype_object_to_string */
/** * The Date.prototype object's 'getYear' routine * * See also: * ECMA-262 v5, AnnexB.B.2.4 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_prototype_get_year (ecma_value_t this_arg) /**< this argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1. */ ECMA_TRY_CATCH (value, ecma_builtin_date_prototype_get_time (this_arg), ret_value); ecma_number_t *this_num_p = ecma_get_number_from_value (value); /* 2. */ if (ecma_number_is_nan (*this_num_p)) { ecma_string_t *nan_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_NAN); ret_value = ecma_make_normal_completion_value (ecma_make_string_value (nan_str_p)); } else { /* 3. */ ecma_number_t *ret_num_p = ecma_alloc_number (); *ret_num_p = ecma_date_year_from_time (ecma_date_local_time (*this_num_p)) - 1900; ret_value = ecma_make_normal_completion_value (ecma_make_number_value (ret_num_p)); } ECMA_FINALIZE (value); return ret_value; } /* ecma_builtin_date_prototype_get_year */
/** * The String object's 'fromCharCode' routine * * See also: * ECMA-262 v5, 15.5.3.2 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_object_from_char_code (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ const ecma_value_t args[], /**< arguments list */ ecma_length_t args_number) /**< number of arguments */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (args_number == 0) { ecma_string_t *ret_str_p = ecma_new_ecma_string_from_utf8 (NULL, 0); return ecma_make_normal_completion_value (ecma_make_string_value (ret_str_p)); } lit_utf8_size_t utf8_buf_size = args_number * LIT_UTF8_MAX_BYTES_IN_CODE_UNIT; ecma_string_t *ret_str_p; MEM_DEFINE_LOCAL_ARRAY (utf8_buf_p, utf8_buf_size, lit_utf8_byte_t); lit_utf8_size_t utf8_buf_used = 0; FIXME ("Support surrogate pairs"); for (ecma_length_t arg_index = 0; arg_index < args_number; 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_completion_value_throw (ret_value)) { mem_heap_free_block (utf8_buf_p); return ret_value; } JERRY_ASSERT (ecma_is_completion_value_empty (ret_value)); } ret_str_p = ecma_new_ecma_string_from_utf8 (utf8_buf_p, utf8_buf_used); MEM_FINALIZE_LOCAL_ARRAY (utf8_buf_p); return ecma_make_normal_completion_value (ecma_make_string_value (ret_str_p)); } /* ecma_builtin_string_object_from_char_code */
/** * The Date.prototype object's 'setTime' routine * * See also: * ECMA-262 v5, 15.9.5.27 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_prototype_set_time (ecma_value_t this_arg, /**< this argument */ ecma_value_t time) /**< time */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (!ecma_is_value_object (this_arg) || ecma_object_get_class_name (ecma_get_object_from_value (this_arg)) != LIT_MAGIC_STRING_DATE_UL) { ret_value = ecma_raise_type_error ("Incompatible type"); } else { /* 1. */ ECMA_OP_TO_NUMBER_TRY_CATCH (t, time, ret_value); ecma_number_t *value_p = ecma_alloc_number (); *value_p = ecma_date_time_clip (t); /* 2. */ ecma_object_t *obj_p = ecma_get_object_from_value (this_arg); ecma_property_t *prim_value_prop_p = ecma_get_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ecma_number_t *prim_value_num_p = ECMA_GET_NON_NULL_POINTER (ecma_number_t, prim_value_prop_p->u.internal_property.value); *prim_value_num_p = *value_p; /* 3. */ ret_value = ecma_make_normal_completion_value (ecma_make_number_value (value_p)); ECMA_OP_TO_NUMBER_FINALIZE (t); } return ret_value; } /* ecma_builtin_date_prototype_set_time */
/** * The Object object's 'getPrototypeOf' routine * * See also: * ECMA-262 v5, 15.2.3.2 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_object_object_get_prototype_of (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg) /**< routine's argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1. */ if (!ecma_is_value_object (arg)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { /* 2. */ ecma_object_t *obj_p = ecma_get_object_from_value (arg); ecma_object_t *prototype_p = ecma_get_object_prototype (obj_p); if (prototype_p) { ret_value = ecma_make_normal_completion_value (ecma_make_object_value (prototype_p)); ecma_ref_object (prototype_p); } else { ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_NULL); } } return ret_value; } /* ecma_builtin_object_object_get_prototype_of */
/** * ToObject operation. * * See also: * ECMA-262 v5, 9.9 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_to_object (ecma_value_t value) /**< ecma-value */ { ecma_check_value_type_is_spec_defined (value); if (ecma_is_value_number (value)) { return ecma_op_create_number_object (value); } else if (ecma_is_value_string (value)) { return ecma_op_create_string_object (&value, 1); } else if (ecma_is_value_object (value)) { return ecma_make_normal_completion_value (ecma_copy_value (value, true)); } else { if (ecma_is_value_undefined (value) || ecma_is_value_null (value)) { return ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { JERRY_ASSERT (ecma_is_value_boolean (value)); return ecma_op_create_boolean_object (value); } } } /* ecma_op_to_object */
/** * Perform 'eval' with code stored in ecma-string * * See also: * ecma_op_eval_chars_buffer * ECMA-262 v5, 15.1.2.1 (steps 2 to 8) * * @return completion value */ ecma_completion_value_t ecma_op_eval (ecma_string_t *code_p, /**< code string */ bool is_direct, /**< is eval called directly (ECMA-262 v5, 15.1.2.1.1) */ bool is_called_from_strict_mode_code) /**< is eval is called from strict mode code */ { ecma_completion_value_t ret_value; lit_utf8_size_t chars_num = ecma_string_get_size (code_p); if (chars_num == 0) { ret_value = ecma_make_normal_completion_value (ecma_make_simple_value (ECMA_SIMPLE_VALUE_UNDEFINED)); } else { MEM_DEFINE_LOCAL_ARRAY (code_utf8_buffer_p, chars_num, lit_utf8_byte_t); const ssize_t buf_size = (ssize_t) chars_num; ssize_t buffer_size_req = ecma_string_to_utf8_string (code_p, code_utf8_buffer_p, buf_size); JERRY_ASSERT (buffer_size_req == buf_size); ret_value = ecma_op_eval_chars_buffer ((jerry_api_char_t *) code_utf8_buffer_p, (size_t) buf_size, is_direct, is_called_from_strict_mode_code); MEM_FINALIZE_LOCAL_ARRAY (code_utf8_buffer_p); } return ret_value; } /* ecma_op_eval */
/** * Number object creation operation. * * See also: ECMA-262 v5, 15.7.2.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_create_number_object (ecma_value_t arg) /**< argument passed to the Number constructor */ { ecma_completion_value_t conv_to_num_completion = ecma_op_to_number (arg); if (!ecma_is_completion_value_normal (conv_to_num_completion)) { return conv_to_num_completion; } ecma_number_t *prim_value_p = ecma_get_number_from_completion_value (conv_to_num_completion); #ifndef CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_NUMBER_PROTOTYPE); #else /* !CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ ecma_object_t *prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_OBJECT_PROTOTYPE); #endif /* CONFIG_ECMA_COMPACT_PROFILE_DISABLE_NUMBER_BUILTIN */ ecma_object_t *obj_p = ecma_create_object (prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (prototype_obj_p); ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_NUMBER_UL; ecma_property_t *prim_value_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_PRIMITIVE_NUMBER_VALUE); ECMA_SET_POINTER (prim_value_prop_p->u.internal_property.value, prim_value_p); return ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); } /* ecma_op_create_number_object */
/** * ImplicitThisValue operation. * * See also: ECMA-262 v5, 10.2.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ ecma_completion_value_t ecma_op_implicit_this_value (ecma_object_t *lex_env_p) /**< lexical environment */ { JERRY_ASSERT (lex_env_p != NULL && ecma_is_lexical_environment (lex_env_p)); if (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE) { return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); } else { JERRY_ASSERT (ecma_get_lex_env_type (lex_env_p) == ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND); if (ecma_get_lex_env_provide_this (lex_env_p)) { ecma_object_t *binding_obj_p = ecma_get_lex_env_binding_object (lex_env_p); ecma_ref_object (binding_obj_p); return ecma_make_normal_completion_value (ecma_make_object_value (binding_obj_p)); } else { return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); } } } /* ecma_op_implicit_this_value */
/** * The Date.prototype object's 'toString' routine * * See also: * ECMA-262 v5, 15.9.5.2 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_prototype_to_string (ecma_value_t this_arg) /**< this argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ECMA_TRY_CATCH (prim_value, ecma_date_get_primitive_value (this_arg), ret_value); ecma_number_t *prim_num_p = ecma_get_number_from_value (prim_value); if (ecma_number_is_nan (*prim_num_p)) { ecma_string_t *magic_str_p = ecma_get_magic_string (LIT_MAGIC_STRING_INVALID_DATE_UL); ret_value = ecma_make_normal_completion_value (ecma_make_string_value (magic_str_p)); } else { ret_value = ecma_date_value_to_string (*prim_num_p); } ECMA_FINALIZE (prim_value); return ret_value; } /* ecma_builtin_date_prototype_to_string */
/** * The Array.prototype's 'toLocaleString' single element operation routine * * See also: * ECMA-262 v5, 15.4.4.3 steps 6-8 and 10.b-d * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ ecma_completion_value_t ecma_builtin_helper_get_to_locale_string_at_index (ecma_object_t *obj_p, /** < this object */ uint32_t index) /** < array index */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ecma_string_t *index_string_p = ecma_new_ecma_string_from_uint32 (index); ECMA_TRY_CATCH (index_value, ecma_op_object_get (obj_p, index_string_p), ret_value); if (ecma_is_value_undefined (index_value) || ecma_is_value_null (index_value)) { ecma_string_t *return_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY); ret_value = ecma_make_normal_completion_value (ecma_make_string_value (return_string_p)); } else { ECMA_TRY_CATCH (index_obj_value, ecma_op_to_object (index_value), ret_value); ecma_object_t *index_obj_p = ecma_get_object_from_value (index_obj_value); ecma_string_t *locale_string_magic_string_p = ecma_get_magic_string (LIT_MAGIC_STRING_TO_LOCALE_STRING_UL); ECMA_TRY_CATCH (to_locale_value, ecma_op_object_get (index_obj_p, locale_string_magic_string_p), ret_value); if (ecma_op_is_callable (to_locale_value)) { ecma_object_t *locale_func_obj_p = ecma_get_object_from_value (to_locale_value); ECMA_TRY_CATCH (call_value, ecma_op_function_call (locale_func_obj_p, ecma_make_object_value (index_obj_p), NULL), ret_value); ret_value = ecma_op_to_string (call_value); ECMA_FINALIZE (call_value); } else { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } ECMA_FINALIZE (to_locale_value); ecma_deref_ecma_string (locale_string_magic_string_p); ECMA_FINALIZE (index_obj_value); } ECMA_FINALIZE (index_value); ecma_deref_ecma_string (index_string_p); return ret_value; } /* ecma_builtin_helper_get_to_locale_string_at_index */
/** * The String.prototype object's 'charAt' routine * * See also: * ECMA-262 v5, 15.5.4.4 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_char_at (ecma_value_t this_arg, /**< this argument */ ecma_value_t arg) /**< routine's argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1 */ ECMA_TRY_CATCH (check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2 */ ECMA_TRY_CATCH (to_string_val, ecma_op_to_string (this_arg), ret_value); /* 3 */ ECMA_OP_TO_NUMBER_TRY_CATCH (index_num, arg, ret_value); /* 4 */ ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val); const ecma_length_t len = ecma_string_get_length (original_string_p); /* 5 */ if (index_num < 0 || index_num >= len || !len) { ret_value = ecma_make_normal_completion_value (ecma_make_string_value ( ecma_get_magic_string (LIT_MAGIC_STRING__EMPTY))); } else { /* 6 */ ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num)); ret_value = ecma_make_normal_completion_value (ecma_make_string_value ( ecma_new_ecma_string_from_code_unit (new_ecma_char))); } ECMA_OP_TO_NUMBER_FINALIZE (index_num); ECMA_FINALIZE (to_string_val); ECMA_FINALIZE (check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_char_at */
/** * The String.prototype object's 'concat' routine * * See also: * ECMA-262 v5, 15.5.4.6 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_concat (ecma_value_t this_arg, /**< this argument */ const ecma_value_t* argument_list_p, /**< arguments list */ ecma_length_t arguments_number) /**< number of arguments */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1 */ ECMA_TRY_CATCH (check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2 */ ECMA_TRY_CATCH (to_string_val, ecma_op_to_string (this_arg), ret_value); /* 3 */ // No copy performed /* 4 */ ecma_string_t *string_to_return = ecma_copy_or_ref_ecma_string (ecma_get_string_from_value (to_string_val)); /* 5 */ for (uint32_t arg_index = 0; arg_index < arguments_number && ecma_is_completion_value_empty (ret_value); ++arg_index) { /* 5a */ /* 5b */ ecma_string_t *string_temp = string_to_return; ECMA_TRY_CATCH (get_arg_string, ecma_op_to_string (argument_list_p[arg_index]), ret_value); string_to_return = ecma_concat_ecma_strings (string_to_return, ecma_get_string_from_value (get_arg_string)); ecma_deref_ecma_string (string_temp); ECMA_FINALIZE (get_arg_string); } /* 6 */ if (ecma_is_completion_value_empty (ret_value)) { ret_value = ecma_make_normal_completion_value (ecma_make_string_value (string_to_return)); } else { ecma_deref_ecma_string (string_to_return); } ECMA_FINALIZE (to_string_val); ECMA_FINALIZE (check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_concat */
/** * The String.prototype object's 'charCodeAt' routine * * See also: * ECMA-262 v5, 15.5.4.5 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_char_code_at (ecma_value_t this_arg, /**< this argument */ ecma_value_t arg) /**< routine's argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1 */ ECMA_TRY_CATCH (check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2 */ ECMA_TRY_CATCH (to_string_val, ecma_op_to_string (this_arg), ret_value); /* 3 */ ECMA_OP_TO_NUMBER_TRY_CATCH (index_num, arg, ret_value); /* 4 */ ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val); const ecma_length_t len = ecma_string_get_length (original_string_p); ecma_number_t *ret_num_p = ecma_alloc_number (); /* 5 */ // When index_num is NaN, then the first two comparisons are false if (index_num < 0 || index_num >= len || (ecma_number_is_nan (index_num) && !len)) { *ret_num_p = ecma_number_make_nan (); } else { /* 6 */ /* * String length is currently uit32_t, but index_num may be bigger, * ToInteger performs floor, while ToUInt32 performs modulo 2^32, * hence after the check 0 <= index_num < len we assume to_uint32 can be used. * We assume to_uint32 (NaN) is 0. */ JERRY_ASSERT (ecma_number_is_nan (index_num) || ecma_number_to_uint32 (index_num) == ecma_number_trunc (index_num)); ecma_char_t new_ecma_char = ecma_string_get_char_at_pos (original_string_p, ecma_number_to_uint32 (index_num)); *ret_num_p = ecma_uint32_to_number (new_ecma_char); } ecma_value_t new_value = ecma_make_number_value (ret_num_p); ret_value = ecma_make_normal_completion_value (new_value); ECMA_OP_TO_NUMBER_FINALIZE (index_num); ECMA_FINALIZE (to_string_val); ECMA_FINALIZE (check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_char_code_at */
/** * ToString operation. * * See also: * ECMA-262 v5, 9.8 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_to_string (ecma_value_t value) /**< ecma-value */ { ecma_check_value_type_is_spec_defined (value); if (unlikely (ecma_is_value_object (value))) { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); ECMA_TRY_CATCH (prim_value, ecma_op_to_primitive (value, ECMA_PREFERRED_TYPE_STRING), ret_value); ret_value = ecma_op_to_string (prim_value); ECMA_FINALIZE (prim_value); return ret_value; } else { ecma_string_t *res_p = NULL; if (ecma_is_value_string (value)) { res_p = ecma_get_string_from_value (value); res_p = ecma_copy_or_ref_ecma_string (res_p); } else if (ecma_is_value_number (value)) { ecma_number_t *num_p = ecma_get_number_from_value (value); res_p = ecma_new_ecma_string_from_number (*num_p); } else if (ecma_is_value_undefined (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_UNDEFINED); } else if (ecma_is_value_null (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_NULL); } else { JERRY_ASSERT (ecma_is_value_boolean (value)); if (ecma_is_value_true (value)) { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_TRUE); } else { res_p = ecma_get_magic_string (LIT_MAGIC_STRING_FALSE); } } return ecma_make_normal_completion_value (ecma_make_string_value (res_p)); } } /* ecma_op_to_string */
/** * The String.prototype object's 'trim' routine * * See also: * ECMA-262 v5, 15.5.4.20 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_trim (ecma_value_t this_arg) /**< this argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1 */ ECMA_TRY_CATCH (check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2 */ ECMA_TRY_CATCH (to_string_val, ecma_op_to_string (this_arg), ret_value); ecma_string_t *original_string_p = ecma_get_string_from_value (to_string_val); /* 3 */ const lit_utf8_size_t size = ecma_string_get_size (original_string_p); const ecma_length_t length = ecma_string_get_size (original_string_p); /* Workaround: avoid repeated call of ecma_string_get_char_at_pos() because its overhead */ lit_utf8_byte_t *original_utf8_str_p = (lit_utf8_byte_t *) mem_heap_alloc_block (size + 1, MEM_HEAP_ALLOC_SHORT_TERM); ecma_string_to_utf8_string (original_string_p, original_utf8_str_p, (ssize_t) size); uint32_t prefix = 0, postfix = 0; uint32_t new_len = 0; while (prefix < length && isspace (lit_utf8_string_code_unit_at (original_utf8_str_p, size, prefix))) { prefix++; } while (postfix < length - prefix && isspace (lit_utf8_string_code_unit_at (original_utf8_str_p, size, length - postfix - 1))) { postfix++; } new_len = prefix < size ? size - prefix - postfix : 0; ecma_string_t *new_str_p = ecma_string_substr (original_string_p, prefix, prefix + new_len); /* 4 */ ret_value = ecma_make_normal_completion_value (ecma_make_string_value (new_str_p)); mem_heap_free_block (original_utf8_str_p); ECMA_FINALIZE (to_string_val); ECMA_FINALIZE (check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_trim */
/** * The Date object's 'now' routine * * See also: * ECMA-262 v5, 15.9.4.4 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_date_now (ecma_value_t this_arg __attr_unused___) /**< this argument */ { /* * FIXME: * Get the real system time. ex: gettimeofday() on Linux * Introduce system macros at first. */ ecma_number_t *now_num_p = ecma_alloc_number (); *now_num_p = ECMA_NUMBER_ZERO; return ecma_make_normal_completion_value (ecma_make_number_value (now_num_p)); } /* ecma_builtin_date_now */
/** * Run specified eval-mode bytecode * * @return completion value */ ecma_completion_value_t vm_run_eval (const bytecode_data_header_t *bytecode_data_p, /**< byte-code data header */ bool is_direct) /**< is eval called in direct mode? */ { vm_instr_counter_t first_instr_index = 0u; opcode_scope_code_flags_t scope_flags = vm_get_scope_flags (bytecode_data_p, first_instr_index++); bool is_strict = ((scope_flags & OPCODE_SCOPE_CODE_FLAGS_STRICT) != 0); ecma_value_t this_binding; ecma_object_t *lex_env_p; /* ECMA-262 v5, 10.4.2 */ if (is_direct) { this_binding = vm_get_this_binding (); lex_env_p = vm_get_lex_env (); } else { this_binding = ecma_make_object_value (ecma_builtin_get (ECMA_BUILTIN_ID_GLOBAL)); lex_env_p = ecma_get_global_environment (); } if (is_strict) { ecma_object_t *strict_lex_env_p = ecma_create_decl_lex_env (lex_env_p); ecma_deref_object (lex_env_p); lex_env_p = strict_lex_env_p; } ecma_completion_value_t completion = vm_run_from_pos (bytecode_data_p, first_instr_index, this_binding, lex_env_p, is_strict, true, NULL); if (ecma_is_completion_value_return (completion)) { completion = ecma_make_normal_completion_value (ecma_get_completion_value_value (completion)); } else { JERRY_ASSERT (ecma_is_completion_value_throw (completion)); } ecma_deref_object (lex_env_p); ecma_free_value (this_binding, true); return completion; } /* vm_run_eval */
/** * RegExp object creation operation. * * See also: ECMA-262 v5, 15.10.4.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_create_regexp_object (ecma_string_t *pattern_p, /**< input pattern */ ecma_string_t *flags_str_p) /**< flags */ { JERRY_ASSERT (pattern_p != NULL); ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); uint8_t flags = 0; if (flags_str_p != NULL) { ECMA_TRY_CATCH (empty, re_parse_regexp_flags (flags_str_p, &flags), ret_value); ECMA_FINALIZE (empty); if (!ecma_is_completion_value_empty (ret_value)) { return ret_value; } } ecma_object_t *re_prototype_obj_p = ecma_builtin_get (ECMA_BUILTIN_ID_REGEXP_PROTOTYPE); ecma_object_t *obj_p = ecma_create_object (re_prototype_obj_p, true, ECMA_OBJECT_TYPE_GENERAL); ecma_deref_object (re_prototype_obj_p); /* Set the internal [[Class]] property */ ecma_property_t *class_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_CLASS); class_prop_p->u.internal_property.value = LIT_MAGIC_STRING_REGEXP_UL; re_initialize_props (obj_p, pattern_p, flags); /* Set bytecode internal property. */ ecma_property_t *bytecode_prop_p; bytecode_prop_p = ecma_create_internal_property (obj_p, ECMA_INTERNAL_PROPERTY_REGEXP_BYTECODE); /* Compile bytecode. */ re_bytecode_t *bc_p = NULL; ECMA_TRY_CATCH (empty, re_compile_bytecode (&bc_p, pattern_p, flags), ret_value); ECMA_SET_POINTER (bytecode_prop_p->u.internal_property.value, bc_p); ret_value = ecma_make_normal_completion_value (ecma_make_object_value (obj_p)); ECMA_FINALIZE (empty); if (ecma_is_completion_value_throw (ret_value)) { ecma_deref_object (obj_p); } return ret_value; } /* ecma_op_create_regexp_object */
/** * The Function.prototype object's 'toString' routine * * See also: * ECMA-262 v5, 15.3.4.2 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_function_prototype_object_to_string (ecma_value_t this_arg) /**< this argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (!ecma_op_is_callable (this_arg)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { ecma_string_t *function_to_string_p = ecma_get_magic_string (LIT_MAGIC_STRING__FUNCTION_TO_STRING); ret_value = ecma_make_normal_completion_value (ecma_make_string_value (function_to_string_p)); } return ret_value; } /* ecma_builtin_function_prototype_object_to_string */
/** * The String.prototype object's 'localeCompare' routine * * See also: * ECMA-262 v5, 15.5.4.9 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_string_prototype_object_locale_compare (ecma_value_t this_arg, /**< this argument */ ecma_value_t arg) /**< routine's argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); /* 1. */ ECMA_TRY_CATCH (this_check_coercible_val, ecma_op_check_object_coercible (this_arg), ret_value); /* 2. */ ECMA_TRY_CATCH (this_to_string_val, ecma_op_to_string (this_arg), ret_value); /* 3. */ ECMA_TRY_CATCH (arg_to_string_val, ecma_op_to_string (arg), ret_value); ecma_string_t *this_string_p = ecma_get_string_from_value (this_to_string_val); ecma_string_t *arg_string_p = ecma_get_string_from_value (arg_to_string_val); ecma_number_t *result_p = ecma_alloc_number (); if (ecma_compare_ecma_strings_relational (this_string_p, arg_string_p)) { *result_p = ecma_int32_to_number (-1); } else if (!ecma_compare_ecma_strings (this_string_p, arg_string_p)) { *result_p = ecma_int32_to_number (1); } else { *result_p = ecma_int32_to_number (0); } ret_value = ecma_make_normal_completion_value (ecma_make_number_value (result_p)); ECMA_FINALIZE (arg_to_string_val); ECMA_FINALIZE (this_to_string_val); ECMA_FINALIZE (this_check_coercible_val); return ret_value; } /* ecma_builtin_string_prototype_object_locale_compare */
/** * The Object object's 'getOwnPropertyDescriptor' routine * * See also: * ECMA-262 v5, 15.2.3.3 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_object_object_get_own_property_descriptor (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg1, /**< routine's first argument */ ecma_value_t arg2) /**< routine's second argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); // 1. if (!ecma_is_value_object (arg1)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); return ret_value; } ecma_object_t *obj_p = ecma_get_object_from_value (arg1); // 2. ECMA_TRY_CATCH (name_str_value, ecma_op_to_string (arg2), ret_value); ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value); // 3. ecma_property_t *prop_p = ecma_op_object_get_own_property (obj_p, name_str_p); if (prop_p != NULL) { ecma_property_descriptor_t prop_desc = ecma_get_property_descriptor_from_property (prop_p); // 4. ecma_object_t* desc_obj_p = ecma_op_from_property_descriptor (&prop_desc); ecma_free_property_descriptor (&prop_desc); ret_value = ecma_make_normal_completion_value (ecma_make_object_value (desc_obj_p)); } else { ret_value = ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); } ECMA_FINALIZE (name_str_value); return ret_value; } /* ecma_builtin_object_object_get_own_property_descriptor */
/** * The Object object's 'create' routine * * See also: * ECMA-262 v5, 15.2.3.5 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_object_object_create (ecma_value_t this_arg, /**< 'this' argument */ ecma_value_t arg1, /**< routine's first argument */ ecma_value_t arg2) /**< routine's second argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); // 1. if (!ecma_is_value_object (arg1) && !ecma_is_value_null (arg1)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { ecma_object_t *obj_p = NULL; if (!ecma_is_value_null (arg1)) { obj_p = ecma_get_object_from_value (arg1); } // 2-3. ecma_object_t *result_obj_p = ecma_op_create_object_object_noarg_and_set_prototype (obj_p); // 4. if (!ecma_is_value_undefined (arg2)) { ECMA_TRY_CATCH (obj, ecma_builtin_object_object_define_properties (this_arg, ecma_make_object_value (result_obj_p), arg2), ret_value); ECMA_FINALIZE (obj); } // 5. if (ecma_is_completion_value_empty (ret_value)) { ret_value = ecma_make_normal_completion_value (ecma_copy_value (ecma_make_object_value (result_obj_p), true)); } ecma_deref_object (result_obj_p); } return ret_value; } /* ecma_builtin_object_object_create */
/** * ToPrimitive operation. * * See also: * ECMA-262 v5, 9.1 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_to_primitive (ecma_value_t value, /**< ecma-value */ ecma_preferred_type_hint_t preferred_type) /**< preferred type hint */ { ecma_check_value_type_is_spec_defined (value); if (ecma_is_value_object (value)) { ecma_object_t *obj_p = ecma_get_object_from_value (value); return ecma_op_object_default_value (obj_p, preferred_type); } else { return ecma_make_normal_completion_value (ecma_copy_value (value, true)); } } /* ecma_op_to_primitive */
/** * The Object object's 'defineProperty' routine * * See also: * ECMA-262 v5, 15.2.3.6 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_object_object_define_property (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg1, /**< routine's first argument */ ecma_value_t arg2, /**< routine's second argument */ ecma_value_t arg3) /**< routine's third argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (!ecma_is_value_object (arg1)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { ecma_object_t *obj_p = ecma_get_object_from_value (arg1); ECMA_TRY_CATCH (name_str_value, ecma_op_to_string (arg2), ret_value); ecma_string_t *name_str_p = ecma_get_string_from_value (name_str_value); ecma_property_descriptor_t prop_desc; ECMA_TRY_CATCH (conv_result, ecma_op_to_property_descriptor (arg3, &prop_desc), ret_value); ECMA_TRY_CATCH (define_own_prop_ret, ecma_op_object_define_own_property (obj_p, name_str_p, &prop_desc, true), ret_value); ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg1, true)); ECMA_FINALIZE (define_own_prop_ret); ecma_free_property_descriptor (&prop_desc); ECMA_FINALIZE (conv_result); ECMA_FINALIZE (name_str_value); } return ret_value; } /* ecma_builtin_object_object_define_property */
/** * [[Get]] ecma general object's operation * * See also: * ECMA-262 v5, 8.6.2; ECMA-262 v5, Table 8 * ECMA-262 v5, 8.12.3 * * @return completion value * Returned value must be freed with ecma_free_completion_value */ ecma_completion_value_t ecma_op_general_object_get (ecma_object_t *obj_p, /**< the object */ ecma_string_t *property_name_p) /**< property name */ { JERRY_ASSERT (obj_p != NULL && !ecma_is_lexical_environment (obj_p)); JERRY_ASSERT (property_name_p != NULL); // 1. const ecma_property_t *prop_p = ecma_op_object_get_property (obj_p, property_name_p); // 2. if (prop_p == NULL) { return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); } // 3. if (prop_p->type == ECMA_PROPERTY_NAMEDDATA) { return ecma_make_normal_completion_value (ecma_copy_value (ecma_get_named_data_property_value (prop_p), true)); } else { // 4. ecma_object_t *getter_p = ecma_get_named_accessor_property_getter (prop_p); // 5. if (getter_p == NULL) { return ecma_make_simple_completion_value (ECMA_SIMPLE_VALUE_UNDEFINED); } else { return ecma_op_function_call (getter_p, ecma_make_object_value (obj_p), NULL); } } JERRY_UNREACHABLE (); } /* ecma_op_general_object_get */
/** * The Object object's 'preventExtensions' routine * * See also: * ECMA-262 v5, 15.2.3.10 * * @return completion value * Returned value must be freed with ecma_free_completion_value. */ static ecma_completion_value_t ecma_builtin_object_object_prevent_extensions (ecma_value_t this_arg __attr_unused___, /**< 'this' argument */ ecma_value_t arg) /**< routine's argument */ { ecma_completion_value_t ret_value = ecma_make_empty_completion_value (); if (!ecma_is_value_object (arg)) { ret_value = ecma_make_throw_obj_completion_value (ecma_new_standard_error (ECMA_ERROR_TYPE)); } else { ecma_object_t *obj_p = ecma_get_object_from_value (arg); ecma_set_object_extensible (obj_p, false); ret_value = ecma_make_normal_completion_value (ecma_copy_value (arg, true)); } return ret_value; } /* ecma_builtin_object_object_prevent_extensions */
/** * Handle calling [[Call]] of built-in String object * * @return completion-value */ ecma_completion_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_completion_value_t ret_value = ecma_make_empty_completion_value (); if (arguments_list_len == 0) { ecma_string_t *str_p = ecma_new_ecma_string_from_magic_string_id (LIT_MAGIC_STRING__EMPTY); ecma_value_t str_value = ecma_make_string_value (str_p); ret_value = ecma_make_normal_completion_value (str_value); } else { ret_value = ecma_op_to_string (arguments_list_p[0]); } return ret_value; } /* ecma_builtin_string_dispatch_call */