diff --git a/src/libecmaobjects/ecma-gc.c b/src/libecmaobjects/ecma-gc.c index 4ced0032a..b93d47431 100644 --- a/src/libecmaobjects/ecma-gc.c +++ b/src/libecmaobjects/ecma-gc.c @@ -97,47 +97,6 @@ ecma_GCInit( void) ecma_GC_Queue = NULL; } /* ecma_GCInit */ -/** - * Garbage collect described value - */ -static void -ecma_GCValue( ecma_Value_t valueDescription) /**< value description */ -{ - switch ( (ecma_Type_t) valueDescription.m_ValueType ) - { - case ECMA_TYPE_SIMPLE: - { - /* doesn't hold additional memory */ - break; - } - - case ECMA_TYPE_NUMBER: - { - ecma_Number_t *pNumber = ecma_GetPointer( valueDescription.m_Value); - ecma_FreeNumber( pNumber); - break; - } - - case ECMA_TYPE_STRING: - { - ecma_ArrayFirstChunk_t *pString = ecma_GetPointer( valueDescription.m_Value); - ecma_FreeArray( pString); - break; - } - - case ECMA_TYPE_OBJECT: - { - ecma_DerefObject( ecma_GetPointer( valueDescription.m_Value)); - break; - } - - case ECMA_TYPE__COUNT: - { - JERRY_UNREACHABLE(); - } - } -} /* ecma_GCValue */ - /** * Garbage collect a named data property */ @@ -147,7 +106,7 @@ ecma_GCNamedDataProperty( ecma_Property_t *pProperty) /**< the property */ JERRY_ASSERT( pProperty->m_Type == ECMA_PROPERTY_NAMEDDATA ); ecma_FreeArray( ecma_GetPointer( pProperty->u.m_NamedDataProperty.m_pName)); - ecma_GCValue( pProperty->u.m_NamedDataProperty.m_Value); + ecma_FreeValue( pProperty->u.m_NamedDataProperty.m_Value); } /* ecma_GCNamedDataProperty */ /** diff --git a/src/libecmaobjects/ecma-helpers-value.c b/src/libecmaobjects/ecma-helpers-value.c index 1c562e40f..17a64a18b 100644 --- a/src/libecmaobjects/ecma-helpers-value.c +++ b/src/libecmaobjects/ecma-helpers-value.c @@ -20,6 +20,8 @@ * @{ */ +#include "ecma-alloc.h" +#include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" #include "globals.h" @@ -103,6 +105,115 @@ ecma_MakeObjectValue( ecma_Object_t* object_p) /**< object to reference in value return object_value; } /* ecma_MakeObjectValue */ +/** + * Copy ecma-value. + * + * Note: + * Operation algorithm. + * switch (valuetype) + * case simple: + * simply return the value as it was passed; + * case number/string: + * copy the number/string + * and return new ecma-value + * pointing to copy of the number/string; + * case object; + * increase reference counter of the object + * and return the value as it was passed. + * + * @return See note. + */ +ecma_Value_t +ecma_CopyValue( const ecma_Value_t value) /**< ecma-value */ +{ + ecma_Value_t value_copy; + + switch ( (ecma_Type_t)value.m_ValueType ) + { + case ECMA_TYPE_SIMPLE: + { + value_copy = value; + } + case ECMA_TYPE_NUMBER: + { + ecma_Number_t *num_p = ecma_GetPointer( value.m_Value); + JERRY_ASSERT( num_p != NULL ); + + ecma_Number_t *number_copy_p = ecma_AllocNumber(); + *number_copy_p = *num_p; + + value_copy = (ecma_Value_t) { .m_ValueType = ECMA_TYPE_NUMBER }; + ecma_SetPointer( value_copy.m_Value, number_copy_p); + } + case ECMA_TYPE_STRING: + { + ecma_ArrayFirstChunk_t *string_p = ecma_GetPointer( value.m_Value); + JERRY_ASSERT( string_p != NULL ); + + ecma_ArrayFirstChunk_t *string_copy_p = ecma_DuplicateEcmaString( string_p); + + value_copy = (ecma_Value_t) { .m_ValueType = ECMA_TYPE_STRING }; + ecma_SetPointer( value_copy.m_Value, string_copy_p); + } + case ECMA_TYPE_OBJECT: + { + ecma_Object_t *obj_p = ecma_GetPointer( value.m_Value); + JERRY_ASSERT( obj_p != NULL ); + + ecma_RefObject( obj_p); + + value_copy = value; + } + case ECMA_TYPE__COUNT: + { + JERRY_UNREACHABLE(); + } + } + + return value_copy; +} /* ecma_CopyValue */ + +/** + * Free memory used for the value + */ +void +ecma_FreeValue( ecma_Value_t value) /**< value description */ +{ + switch ( (ecma_Type_t) value.m_ValueType ) + { + case ECMA_TYPE_SIMPLE: + { + /* doesn't hold additional memory */ + break; + } + + case ECMA_TYPE_NUMBER: + { + ecma_Number_t *pNumber = ecma_GetPointer( value.m_Value); + ecma_FreeNumber( pNumber); + break; + } + + case ECMA_TYPE_STRING: + { + ecma_ArrayFirstChunk_t *pString = ecma_GetPointer( value.m_Value); + ecma_FreeArray( pString); + break; + } + + case ECMA_TYPE_OBJECT: + { + ecma_DerefObject( ecma_GetPointer( value.m_Value)); + break; + } + + case ECMA_TYPE__COUNT: + { + JERRY_UNREACHABLE(); + } + } +} /* ecma_FreeValue */ + /** * Completion value constructor */ diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index e0dd15d56..f2111c20d 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -49,6 +49,9 @@ extern bool ecma_IsValueTrue( ecma_Value_t value); extern ecma_Value_t ecma_MakeSimpleValue( ecma_SimpleValue_t value); extern ecma_Value_t ecma_MakeObjectValue( ecma_Object_t* object_p); +extern ecma_Value_t ecma_CopyValue( const ecma_Value_t value); +extern void ecma_FreeValue( const ecma_Value_t value); + extern ecma_CompletionValue_t ecma_MakeCompletionValue( ecma_CompletionType_t type, ecma_Value_t value, uint8_t target); extern ecma_CompletionValue_t ecma_MakeThrowValue( ecma_Object_t *exception_p);