From f7cdb454edbf88c9eecbe362bce7a08b1b8693c3 Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Fri, 22 Aug 2014 14:40:58 +0400 Subject: [PATCH] Implementing ToString operation (ecma_op_to_string) --- src/libecmaoperations/ecma-conversion.c | 97 ++++++++++++++++++++++ src/libecmaoperations/ecma-conversion.h | 1 + src/libecmaoperations/ecma-magic-strings.c | 3 + src/libecmaoperations/ecma-magic-strings.h | 3 + 4 files changed, 104 insertions(+) diff --git a/src/libecmaoperations/ecma-conversion.c b/src/libecmaoperations/ecma-conversion.c index 1cef6ce38..ae181e33e 100644 --- a/src/libecmaoperations/ecma-conversion.c +++ b/src/libecmaoperations/ecma-conversion.c @@ -20,6 +20,8 @@ #include "ecma-conversion.h" #include "ecma-exceptions.h" #include "ecma-globals.h" +#include "ecma-magic-strings.h" +#include "ecma-try-catch-macro.h" #include "jerry-libc.h" /** \addtogroup ecma ---TODO--- @@ -300,6 +302,101 @@ ecma_op_to_number (ecma_value_t value) /**< ecma-value */ JERRY_UNREACHABLE(); } /* ecma_op_to_number */ +/** + * 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 */ +{ + if (unlikely (value.value_type == ECMA_TYPE_OBJECT)) + { + ecma_completion_value_t ret_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.value); + + ECMA_FINALIZE (prim_value); + + return ret_value; + } + + ecma_string_t *res_p = NULL; + + switch ((ecma_type_t) value.value_type) + { + case ECMA_TYPE_SIMPLE: + { + switch ((ecma_simple_value_t) value.value) + { + case ECMA_SIMPLE_VALUE_UNDEFINED: + { + res_p = ecma_get_magic_string (ECMA_MAGIC_STRING_UNDEFINED); + break; + } + case ECMA_SIMPLE_VALUE_NULL: + { + res_p = ecma_get_magic_string (ECMA_MAGIC_STRING_NULL); + break; + } + case ECMA_SIMPLE_VALUE_FALSE: + { + res_p = ecma_get_magic_string (ECMA_MAGIC_STRING_FALSE); + break; + } + case ECMA_SIMPLE_VALUE_TRUE: + { + res_p = ecma_get_magic_string (ECMA_MAGIC_STRING_TRUE); + break; + } + + case ECMA_SIMPLE_VALUE_EMPTY: + case ECMA_SIMPLE_VALUE_ARRAY_REDIRECT: + case ECMA_SIMPLE_VALUE__COUNT: + { + JERRY_UNREACHABLE (); + } + } + + break; + } + + case ECMA_TYPE_NUMBER: + { + ecma_number_t *num_p = ECMA_GET_POINTER (value.value); + res_p = ecma_new_ecma_string_from_number (*num_p); + + break; + } + + case ECMA_TYPE_STRING: + { + res_p = ECMA_GET_POINTER (value.value); + ecma_ref_ecma_string (res_p); + + break; + } + + case ECMA_TYPE_OBJECT: + case ECMA_TYPE__COUNT: + { + JERRY_UNREACHABLE (); + } + } + + return ecma_make_completion_value (ECMA_COMPLETION_TYPE_NORMAL, + ecma_make_string_value (res_p), + ECMA_TARGET_ID_RESERVED); +} /* ecma_op_to_string */ + /** * ToObject operation. * diff --git a/src/libecmaoperations/ecma-conversion.h b/src/libecmaoperations/ecma-conversion.h index be1ef4a86..14fe28efc 100644 --- a/src/libecmaoperations/ecma-conversion.h +++ b/src/libecmaoperations/ecma-conversion.h @@ -45,6 +45,7 @@ extern bool ecma_op_same_value (ecma_value_t x, ecma_value_t y); extern ecma_completion_value_t ecma_op_to_primitive (ecma_value_t value, ecma_preferred_type_hint_t preferred_type); extern ecma_completion_value_t ecma_op_to_boolean (ecma_value_t value); extern ecma_completion_value_t ecma_op_to_number (ecma_value_t value); +extern ecma_completion_value_t ecma_op_to_string (ecma_value_t value); extern ecma_completion_value_t ecma_op_to_object (ecma_value_t value); /** diff --git a/src/libecmaoperations/ecma-magic-strings.c b/src/libecmaoperations/ecma-magic-strings.c index 5514913be..b3074a9f9 100644 --- a/src/libecmaoperations/ecma-magic-strings.c +++ b/src/libecmaoperations/ecma-magic-strings.c @@ -43,6 +43,9 @@ ecma_get_magic_string_zt (ecma_magic_string_id_t id) /**< magic string id */ case ECMA_MAGIC_STRING_CALLER: return (ecma_char_t*) "caller"; case ECMA_MAGIC_STRING_CALLEE: return (ecma_char_t*) "callee"; case ECMA_MAGIC_STRING_UNDEFINED: return (ecma_char_t*) "undefined"; + case ECMA_MAGIC_STRING_NULL: return (ecma_char_t*) "null"; + case ECMA_MAGIC_STRING_FALSE: return (ecma_char_t*) "false"; + case ECMA_MAGIC_STRING_TRUE: return (ecma_char_t*) "true"; case ECMA_MAGIC_STRING_LENGTH: return (ecma_char_t*) "length"; case ECMA_MAGIC_STRING_NAN: return (ecma_char_t*) "NaN"; case ECMA_MAGIC_STRING_INFINITY: return (ecma_char_t*) "Infinity"; diff --git a/src/libecmaoperations/ecma-magic-strings.h b/src/libecmaoperations/ecma-magic-strings.h index 750a70551..2481e5d42 100644 --- a/src/libecmaoperations/ecma-magic-strings.h +++ b/src/libecmaoperations/ecma-magic-strings.h @@ -37,6 +37,9 @@ typedef enum ECMA_MAGIC_STRING_CALLER, /**< "caller" */ ECMA_MAGIC_STRING_CALLEE, /**< "callee" */ ECMA_MAGIC_STRING_UNDEFINED,/**< "undefined" */ + ECMA_MAGIC_STRING_NULL,/**< "null" */ + ECMA_MAGIC_STRING_FALSE,/**< "false" */ + ECMA_MAGIC_STRING_TRUE,/**< "true" */ ECMA_MAGIC_STRING_LENGTH, /**< "length" */ ECMA_MAGIC_STRING_NAN, /**< "NaN" */ ECMA_MAGIC_STRING_INFINITY /**< "Infinity" */