From c8605bb4d14ebe5e080ea921878b03ed22203fff Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Wed, 16 Jul 2014 21:36:59 +0400 Subject: [PATCH] Renaming ecma_GC*Property to ecma_Free*Property and moving them to ecma-helpers.c; introducing ecma_CreateNamedProperty, ecma_GetNamedProperty, ecma_GetNamedDataProperty, ecma_FreeProperty (extracted from ecma_GCRun), ecma_DeleteProperty; removing length argument of ecma_NewEcmaString helper. --- src/libecmaobjects/ecma-gc.c | 100 +----------- src/libecmaobjects/ecma-helpers.c | 249 +++++++++++++++++++++++++++++- src/libecmaobjects/ecma-helpers.h | 15 +- 3 files changed, 256 insertions(+), 108 deletions(-) diff --git a/src/libecmaobjects/ecma-gc.c b/src/libecmaobjects/ecma-gc.c index 8217d03c0..859f39efa 100644 --- a/src/libecmaobjects/ecma-gc.c +++ b/src/libecmaobjects/ecma-gc.c @@ -97,79 +97,6 @@ ecma_GCInit( void) ecma_GC_Queue = NULL; } /* ecma_GCInit */ -/** - * Garbage collect a named data property - */ -static void -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_FreeValue( pProperty->u.m_NamedDataProperty.m_Value); -} /* ecma_GCNamedDataProperty */ - -/** - * Garbage collect a named accessor property - */ -static void -ecma_GCNamedAccessorProperty( ecma_Property_t *pProperty) /**< the property */ -{ - JERRY_ASSERT( pProperty->m_Type == ECMA_PROPERTY_NAMEDACCESSOR ); - - ecma_FreeArray( ecma_GetPointer( pProperty->u.m_NamedAccessorProperty.m_pName)); - - ecma_Object_t *pGet = ecma_GetPointer(pProperty->u.m_NamedAccessorProperty.m_pGet); - ecma_Object_t *pSet = ecma_GetPointer(pProperty->u.m_NamedAccessorProperty.m_pSet); - - if ( pGet != NULL ) - { - ecma_DerefObject( pGet); - } - - if ( pSet != NULL ) - { - ecma_DerefObject( pSet); - } -} /* ecma_GCNamedAccessorProperty */ - -/** - * Garbage collect an internal property - */ -static void -ecma_GCInternalProperty( ecma_Property_t *pProperty) /**< the property */ -{ - JERRY_ASSERT( pProperty->m_Type == ECMA_PROPERTY_INTERNAL ); - - ecma_InternalPropertyId_t propertyId = pProperty->u.m_InternalProperty.m_InternalPropertyType; - uint32_t propertyValue = pProperty->u.m_InternalProperty.m_Value; - - switch ( propertyId ) - { - case ECMA_INTERNAL_PROPERTY_CLASS: /* a string */ - case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* an array */ - case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* an array */ - { - ecma_FreeArray( ecma_GetPointer( propertyValue)); - break; - } - - case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ - case ECMA_INTERNAL_PROPERTY_BINDING_OBJECT: /* an object */ - { - ecma_DerefObject( ecma_GetPointer( propertyValue)); - break; - } - - case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_Object_t */ - case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_Object_t */ - case ECMA_INTERNAL_PROPERTY_PROVIDE_THIS: /* a boolean flag */ - { - break; - } - } -} /* ecma_GCInternalProperty */ - /** * Run garbage collecting */ @@ -187,32 +114,9 @@ ecma_GCRun( void) property != NULL; property = pNextProperty ) { - switch ( (ecma_PropertyType_t) property->m_Type ) - { - case ECMA_PROPERTY_NAMEDDATA: - { - ecma_GCNamedDataProperty( property); - - break; - } - - case ECMA_PROPERTY_NAMEDACCESSOR: - { - ecma_GCNamedAccessorProperty( property); - - break; - } - - case ECMA_PROPERTY_INTERNAL: - { - ecma_GCInternalProperty( property); - - break; - } - } - pNextProperty = ecma_GetPointer( property->m_pNextProperty); - ecma_DeallocProperty( property); + + ecma_FreeProperty( property); } if ( pObject->m_IsLexicalEnvironment ) diff --git a/src/libecmaobjects/ecma-helpers.c b/src/libecmaobjects/ecma-helpers.c index e639ba007..a49c180db 100644 --- a/src/libecmaobjects/ecma-helpers.c +++ b/src/libecmaobjects/ecma-helpers.c @@ -21,6 +21,7 @@ */ #include "ecma-alloc.h" +#include "ecma-gc.h" #include "ecma-globals.h" #include "ecma-helpers.h" #include "jerry-libc.h" @@ -200,6 +201,39 @@ ecma_GetInternalProperty(ecma_Object_t *pObject, /**< object descriptor */ return pProperty; } /* ecma_GetInternalProperty */ +/** + * Create named data property with given name, attributes and undefined value + * in the specified object. + * + * @return pointer to newly created property + */ +ecma_Property_t* +ecma_CreateNamedProperty(ecma_Object_t *obj_p, /**< object */ + ecma_Char_t *name_p, /**< property name */ + ecma_PropertyWritableValue_t writable, /**< 'writable' attribute */ + ecma_PropertyEnumerableValue_t enumerable, /**< 'enumerable' attribute */ + ecma_PropertyConfigurableValue_t configurable) /**< 'configurable' attribute */ +{ + JERRY_ASSERT( obj_p != NULL && name_p != NULL ); + + ecma_Property_t *prop = ecma_AllocProperty(); + + prop->m_Type = ECMA_PROPERTY_NAMEDDATA; + + ecma_SetPointer( prop->u.m_NamedDataProperty.m_pName, ecma_NewEcmaString( name_p)); + + prop->u.m_NamedDataProperty.m_Writable = writable; + prop->u.m_NamedDataProperty.m_Enumerable = enumerable; + prop->u.m_NamedDataProperty.m_Configurable = configurable; + + prop->u.m_NamedDataProperty.m_Value = ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_UNDEFINED); + + ecma_SetPointer( prop->m_pNextProperty, ecma_GetPointer( obj_p->m_pProperties)); + ecma_SetPointer( obj_p->m_pProperties, prop); + + return prop; +} /* ecma_CreateNamedProperty */ + /** * Find named data property or named access property in specified object. * @@ -207,11 +241,11 @@ ecma_GetInternalProperty(ecma_Object_t *pObject, /**< object descriptor */ * NULL - otherwise. */ ecma_Property_t* -ecma_FindNamedProperty(ecma_Object_t *obj_p, /**< object to find property in */ - ecma_Char_t *string_p) /**< property's name */ +ecma_FindNamedProperty(ecma_Object_t *obj_p, /**< object to find property in */ + ecma_Char_t *name_p) /**< property's name */ { JERRY_ASSERT( obj_p != NULL ); - JERRY_ASSERT( string_p != NULL ); + JERRY_ASSERT( name_p != NULL ); for ( ecma_Property_t *property_p = ecma_GetPointer( obj_p->m_pProperties); property_p != NULL; @@ -232,7 +266,7 @@ ecma_FindNamedProperty(ecma_Object_t *obj_p, /**< object to find property in */ JERRY_ASSERT( property_name_p != NULL ); - if ( ecma_CompareCharBufferToEcmaString( string_p, property_name_p) ) + if ( ecma_CompareCharBufferToEcmaString( name_p, property_name_p) ) { return property_p; } @@ -241,17 +275,218 @@ ecma_FindNamedProperty(ecma_Object_t *obj_p, /**< object to find property in */ return NULL; } /* ecma_FindNamedProperty */ +/** + * Get named data property or named access property in specified object. + * + * Warning: + * the property must exist + * + * @return pointer to the property, if it is found, + * NULL - otherwise. + */ +ecma_Property_t* +ecma_GetNamedProperty(ecma_Object_t *obj_p, /**< object to find property in */ + ecma_Char_t *name_p) /**< property's name */ +{ + JERRY_ASSERT( obj_p != NULL ); + JERRY_ASSERT( name_p != NULL ); + + ecma_Property_t *property_p = ecma_FindNamedProperty( obj_p, name_p); + + JERRY_ASSERT( property_p != NULL ); + + return property_p; +} /* ecma_GetNamedProperty */ + +/** + * Get named data property in specified object. + * + * Warning: + * the property must exist and be named data property + * + * @return pointer to the property, if it is found, + * NULL - otherwise. + */ +ecma_Property_t* +ecma_GetNamedDataProperty(ecma_Object_t *obj_p, /**< object to find property in */ + ecma_Char_t *name_p) /**< property's name */ +{ + JERRY_ASSERT( obj_p != NULL ); + JERRY_ASSERT( name_p != NULL ); + + ecma_Property_t *property_p = ecma_FindNamedProperty( obj_p, name_p); + + JERRY_ASSERT( property_p != NULL && property_p->m_Type == ECMA_PROPERTY_NAMEDDATA ); + + return property_p; +} /* ecma_GetNamedDataProperty */ + +/** + * Free the named data property and values it references. + */ +void +ecma_FreeNamedDataProperty( 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_FreeValue( pProperty->u.m_NamedDataProperty.m_Value); + + ecma_DeallocProperty( pProperty); +} /* ecma_FreeNamedDataProperty */ + +/** + * Free the named accessor property and values it references. + */ +void +ecma_FreeNamedAccessorProperty( ecma_Property_t *pProperty) /**< the property */ +{ + JERRY_ASSERT( pProperty->m_Type == ECMA_PROPERTY_NAMEDACCESSOR ); + + ecma_FreeArray( ecma_GetPointer( pProperty->u.m_NamedAccessorProperty.m_pName)); + + ecma_Object_t *pGet = ecma_GetPointer(pProperty->u.m_NamedAccessorProperty.m_pGet); + ecma_Object_t *pSet = ecma_GetPointer(pProperty->u.m_NamedAccessorProperty.m_pSet); + + if ( pGet != NULL ) + { + ecma_DerefObject( pGet); + } + + if ( pSet != NULL ) + { + ecma_DerefObject( pSet); + } + + ecma_DeallocProperty( pProperty); +} /* ecma_FreeNamedAccessorProperty */ + +/** + * Free the internal property and values it references. + */ +void +ecma_FreeInternalProperty( ecma_Property_t *pProperty) /**< the property */ +{ + JERRY_ASSERT( pProperty->m_Type == ECMA_PROPERTY_INTERNAL ); + + ecma_InternalPropertyId_t propertyId = pProperty->u.m_InternalProperty.m_InternalPropertyType; + uint32_t propertyValue = pProperty->u.m_InternalProperty.m_Value; + + switch ( propertyId ) + { + case ECMA_INTERNAL_PROPERTY_CLASS: /* a string */ + case ECMA_INTERNAL_PROPERTY_NUMBER_INDEXED_ARRAY_VALUES: /* an array */ + case ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES: /* an array */ + { + ecma_FreeArray( ecma_GetPointer( propertyValue)); + break; + } + + case ECMA_INTERNAL_PROPERTY_SCOPE: /* a lexical environment */ + case ECMA_INTERNAL_PROPERTY_BINDING_OBJECT: /* an object */ + { + ecma_DerefObject( ecma_GetPointer( propertyValue)); + break; + } + + case ECMA_INTERNAL_PROPERTY_PROTOTYPE: /* the property's value is located in ecma_Object_t */ + case ECMA_INTERNAL_PROPERTY_EXTENSIBLE: /* the property's value is located in ecma_Object_t */ + case ECMA_INTERNAL_PROPERTY_PROVIDE_THIS: /* a boolean flag */ + { + break; + } + } + + ecma_DeallocProperty( pProperty); +} /* ecma_FreeInternalProperty */ + +/** + * Free the property and values it references. + */ +void +ecma_FreeProperty(ecma_Property_t *prop_p) /**< property */ +{ + switch ( (ecma_PropertyType_t) prop_p->m_Type ) + { + case ECMA_PROPERTY_NAMEDDATA: + { + ecma_FreeNamedDataProperty( prop_p); + + break; + } + + case ECMA_PROPERTY_NAMEDACCESSOR: + { + ecma_FreeNamedAccessorProperty( prop_p); + + break; + } + + case ECMA_PROPERTY_INTERNAL: + { + ecma_FreeInternalProperty( prop_p); + + break; + } + } +} /* ecma_FreeProperty */ + +/** + * Delete the object's property. + * + * Warning: specified property must be owned by specified object. + */ +void +ecma_DeleteProperty(ecma_Object_t *obj_p, /**< object */ + ecma_Property_t *prop_p) /**< property */ +{ + for ( ecma_Property_t *cur_prop_p = ecma_GetPointer( obj_p->m_pProperties), *prev_prop_p = NULL, *next_prop_p; + cur_prop_p != NULL; + prev_prop_p = cur_prop_p, cur_prop_p = next_prop_p ) + { + next_prop_p = ecma_GetPointer( cur_prop_p->m_pNextProperty); + + if ( cur_prop_p == prop_p ) + { + ecma_FreeProperty( prop_p); + + if ( prev_prop_p == NULL ) + { + ecma_SetPointer( obj_p->m_pProperties, next_prop_p); + } else + { + ecma_SetPointer( prev_prop_p->m_pNextProperty, next_prop_p); + } + + return; + } + } + + JERRY_UNREACHABLE(); +} /* ecma_DeleteProperty */ + /** * Allocate new ecma-string and fill it with characters from specified buffer * * @return Pointer to first chunk of an array, containing allocated string */ ecma_ArrayFirstChunk_t* -ecma_NewEcmaString(const ecma_Char_t *pString, /**< buffer of characters */ - ecma_Length_t length) /**< length of string, in characters */ +ecma_NewEcmaString(const ecma_Char_t *pString) /**< zero-terminated string of ecma-characters */ { - JERRY_ASSERT( length == 0 || pString != NULL ); + ecma_Length_t length = 0; + /* + * TODO: Do not precalculate length. + */ + if ( pString != NULL ) + { + const ecma_Char_t *iter_p = pString; + while ( *iter_p++ ) + { + length++; + } + } + ecma_ArrayFirstChunk_t *pStringFirstChunk = ecma_AllocArrayFirstChunk(); pStringFirstChunk->m_Header.m_UnitNumber = length; diff --git a/src/libecmaobjects/ecma-helpers.h b/src/libecmaobjects/ecma-helpers.h index f2111c20d..1ac4354d7 100644 --- a/src/libecmaobjects/ecma-helpers.h +++ b/src/libecmaobjects/ecma-helpers.h @@ -62,11 +62,20 @@ extern ecma_Object_t* ecma_CreateLexicalEnvironment( ecma_Object_t *pOuterLexica extern ecma_Property_t* ecma_CreateInternalProperty(ecma_Object_t *pObject, ecma_InternalPropertyId_t propertyId); extern ecma_Property_t* ecma_FindInternalProperty(ecma_Object_t *pObject, ecma_InternalPropertyId_t propertyId); extern ecma_Property_t* ecma_GetInternalProperty(ecma_Object_t *pObject, ecma_InternalPropertyId_t propertyId); -extern ecma_Property_t* ecma_SetInternalProperty(ecma_Object_t *pObject, ecma_InternalPropertyId_t propertyId); -extern ecma_Property_t *ecma_FindNamedProperty(ecma_Object_t *obj_p, ecma_Char_t *string_p); +extern ecma_Property_t *ecma_CreateNamedProperty(ecma_Object_t *obj_p, ecma_Char_t *name_p, ecma_PropertyWritableValue_t writable, ecma_PropertyEnumerableValue_t enumerable, ecma_PropertyConfigurableValue_t configurable); +extern ecma_Property_t *ecma_FindNamedProperty(ecma_Object_t *obj_p, ecma_Char_t *name_p); +extern ecma_Property_t *ecma_GetNamedProperty(ecma_Object_t *obj_p, ecma_Char_t *name_p); +extern ecma_Property_t *ecma_GetNamedDataProperty(ecma_Object_t *obj_p, ecma_Char_t *name_p); -extern ecma_ArrayFirstChunk_t* ecma_NewEcmaString( const ecma_Char_t *pString, ecma_Length_t length); +extern void ecma_FreeInternalProperty(ecma_Property_t *prop_p); +extern void ecma_FreeNamedDataProperty(ecma_Property_t *prop_p); +extern void ecma_FreeNamedAccessorProperty(ecma_Property_t *prop_p); +extern void ecma_FreeProperty(ecma_Property_t *prop_p); + +extern void ecma_DeleteProperty( ecma_Object_t *obj_p, ecma_Property_t *prop_p); + +extern ecma_ArrayFirstChunk_t* ecma_NewEcmaString( const ecma_Char_t *pString); extern ssize_t ecma_CopyEcmaStringCharsToBuffer( ecma_ArrayFirstChunk_t *pFirstChunk, uint8_t *pBuffer, size_t bufferSize); extern ecma_ArrayFirstChunk_t* ecma_DuplicateEcmaString( ecma_ArrayFirstChunk_t *pFirstChunk); extern bool ecma_CompareCharBufferToEcmaString( ecma_Char_t *pString, ecma_ArrayFirstChunk_t *pEcmaString);