Merge branch 'master' into geppetto

This commit is contained in:
Ilmir Usmanov 2014-07-16 22:24:42 +04:00
commit c53eccbdd6
11 changed files with 941 additions and 241 deletions

View File

@ -48,6 +48,8 @@ JERRY_STATIC_ASSERT( sizeof (ecma_CompletionValue_t) == sizeof(uint32_t) );
/**
* Template of an allocation routine.
*
* FIXME: Run GC only if allocation failed.
*/
#define ALLOC( ecmaType) ecma_ ## ecmaType ## _t * \
ecma_Alloc ## ecmaType (void) \
@ -62,13 +64,13 @@ ecma_Alloc ## ecmaType (void) \
}
/**
* Free routine template
* Deallocation routine template
*/
#define FREE( ecmaType) void \
ecma_Free ## ecmaType( ecma_ ## ecmaType ## _t *p ## ecmaType) \
#define DEALLOC( ecmaType) void \
ecma_Dealloc ## ecmaType( ecma_ ## ecmaType ## _t *p ## ecmaType) \
{ \
mem_PoolsFree( mem_SizeToPoolChunkType( sizeof(ecma_ ## ecmaType ## _t)), \
(uint8_t*) p ## ecmaType); \
(uint8_t*) p ## ecmaType); \
}
/**
@ -76,7 +78,7 @@ ecma_Free ## ecmaType( ecma_ ## ecmaType ## _t *p ## ecmaType) \
*/
#define DECLARE_ROUTINES_FOR( ecmaType) \
ALLOC( ecmaType) \
FREE( ecmaType)
DEALLOC( ecmaType)
DECLARE_ROUTINES_FOR (Object)
DECLARE_ROUTINES_FOR (Property)

View File

@ -33,9 +33,9 @@
extern ecma_Object_t *ecma_AllocObject(void);
/**
* Free memory from an ecma-object
* Dealloc memory from an ecma-object
*/
extern void ecma_FreeObject( ecma_Object_t *pObject);
extern void ecma_DeallocObject( ecma_Object_t *pObject);
/**
* Allocate memory for ecma-property
@ -45,9 +45,9 @@ extern void ecma_FreeObject( ecma_Object_t *pObject);
extern ecma_Property_t *ecma_AllocProperty(void);
/**
* Free memory from an ecma-property
* Dealloc memory from an ecma-property
*/
extern void ecma_FreeProperty( ecma_Property_t *pProperty);
extern void ecma_DeallocProperty( ecma_Property_t *pProperty);
/**
* Allocate memory for ecma-number
@ -57,9 +57,9 @@ extern void ecma_FreeProperty( ecma_Property_t *pProperty);
extern ecma_Number_t *ecma_AllocNumber(void);
/**
* Free memory from an ecma-number
* Dealloc memory from an ecma-number
*/
extern void ecma_FreeNumber( ecma_Number_t *pNumber);
extern void ecma_DeallocNumber( ecma_Number_t *pNumber);
/**
* Allocate memory for first chunk of an ecma-array
@ -69,9 +69,9 @@ extern void ecma_FreeNumber( ecma_Number_t *pNumber);
extern ecma_ArrayFirstChunk_t *ecma_AllocArrayFirstChunk(void);
/**
* Free memory from first chunk of an ecma-array
* Dealloc memory from first chunk of an ecma-array
*/
extern void ecma_FreeArrayFirstChunk( ecma_ArrayFirstChunk_t *pFirstChunk);
extern void ecma_DeallocArrayFirstChunk( ecma_ArrayFirstChunk_t *pFirstChunk);
/**
* Allocate memory for non-first chunk of an ecma-array
@ -81,13 +81,13 @@ extern void ecma_FreeArrayFirstChunk( ecma_ArrayFirstChunk_t *pFirstChunk);
extern ecma_ArrayNonFirstChunk_t *ecma_AllocArrayNonFirstChunk(void);
/**
* Free memory from non-first chunk of an ecma-array
* Dealloc memory from non-first chunk of an ecma-array
*/
extern void ecma_FreeArrayNonFirstChunk( ecma_ArrayNonFirstChunk_t *pNumber);
extern void ecma_DeallocArrayNonFirstChunk( ecma_ArrayNonFirstChunk_t *pNumber);
#endif /* JERRY_ECMA_ALLOC_H */
/**
* @}
* @}
*/
*/

View File

@ -97,120 +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
*/
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_GCValue( 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
*/
@ -228,31 +114,8 @@ 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_FreeProperty( property);
}
@ -274,7 +137,7 @@ ecma_GCRun( void)
}
}
ecma_FreeObject( pObject);
ecma_DeallocObject( pObject);
}
} /* ecma_RunGC */

View File

@ -153,6 +153,33 @@ typedef enum {
ECMA_INTERNAL_PROPERTY_STRING_INDEXED_ARRAY_VALUES
} ecma_InternalPropertyId_t;
/**
* Property's 'Writable' attribute's values description.
*/
typedef enum
{
ECMA_PROPERTY_WRITABLE, /**< property's 'Writable' attribute is true */
ECMA_PROPERTY_NOT_WRITABLE /**< property's 'Writable' attribute is false */
} ecma_PropertyWritableValue_t;
/**
* Property's 'Enumerable' attribute's values description.
*/
typedef enum
{
ECMA_PROPERTY_ENUMERABLE, /**< property's 'Enumerable' attribute is true */
ECMA_PROPERTY_NOT_ENUMERABLE /**< property's 'Enumerable' attribute is false */
} ecma_PropertyEnumerableValue_t;
/**
* Property's 'Configurable' attribute's values description.
*/
typedef enum
{
ECMA_PROPERTY_CONFIGURABLE, /**< property's 'Configurable' attribute is true */
ECMA_PROPERTY_NOT_CONFIGURABLE /**< property's 'Configurable' attribute is false */
} ecma_PropertyConfigurableValue_t;
/**
* Description of ecma-property.
*/
@ -171,13 +198,13 @@ typedef struct ecma_Property_t {
/** Compressed pointer to property's name (pointer to String) */
unsigned int m_pName : ECMA_POINTER_FIELD_WIDTH;
/** Attribute 'Writable' */
/** Attribute 'Writable' (ecma_PropertyWritableValue_t) */
unsigned int m_Writable : 1;
/** Attribute 'Enumerable' */
/** Attribute 'Enumerable' (ecma_PropertyEnumerableValue_t) */
unsigned int m_Enumerable : 1;
/** Attribute 'Configurable' */
/** Attribute 'Configurable' (ecma_PropertyConfigurableValue_t) */
unsigned int m_Configurable : 1;
/** Value */
@ -189,10 +216,10 @@ typedef struct ecma_Property_t {
/** Compressed pointer to property's name (pointer to String) */
unsigned int m_pName : ECMA_POINTER_FIELD_WIDTH;
/** Attribute 'Enumerable' */
/** Attribute 'Enumerable' (ecma_PropertyEnumerableValue_t) */
unsigned int m_Enumerable : 1;
/** Attribute 'Configurable' */
/** Attribute 'Configurable' (ecma_PropertyConfigurableValue_t) */
unsigned int m_Configurable : 1;
/** Compressed pointer to property's getter */

View File

@ -20,6 +20,8 @@
* @{
*/
#include "ecma-alloc.h"
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "globals.h"
@ -31,10 +33,10 @@
* false - otherwise.
*/
bool
ecma_IsUndefinedValue( ecma_Value_t value) /**< ecma-value */
ecma_IsValueUndefined( ecma_Value_t value) /**< ecma-value */
{
return ( value.m_ValueType == ECMA_TYPE_SIMPLE && value.m_Value == ECMA_SIMPLE_VALUE_UNDEFINED );
} /* ecma_IsUndefinedValue */
} /* ecma_IsValueUndefined */
/**
* Check if the value is null.
@ -43,10 +45,10 @@ ecma_IsUndefinedValue( ecma_Value_t value) /**< ecma-value */
* false - otherwise.
*/
bool
ecma_IsNullValue( ecma_Value_t value) /**< ecma-value */
ecma_IsValueNull( ecma_Value_t value) /**< ecma-value */
{
return ( value.m_ValueType == ECMA_TYPE_SIMPLE && value.m_Value == ECMA_SIMPLE_VALUE_NULL );
} /* ecma_IsNullValue */
} /* ecma_IsValueNull */
/**
* Check if the value is boolean.
@ -55,11 +57,11 @@ ecma_IsNullValue( ecma_Value_t value) /**< ecma-value */
* false - otherwise.
*/
bool
ecma_IsBooleanValue( ecma_Value_t value) /**< ecma-value */
ecma_IsValueBoolean( ecma_Value_t value) /**< ecma-value */
{
return ( ( value.m_ValueType == ECMA_TYPE_SIMPLE && value.m_Value == ECMA_SIMPLE_VALUE_FALSE )
|| ( value.m_ValueType == ECMA_TYPE_SIMPLE && value.m_Value == ECMA_SIMPLE_VALUE_TRUE ) );
} /* ecma_IsBooleanValue */
} /* ecma_IsValueBoolean */
/**
* Check if the value is true.
@ -73,7 +75,7 @@ ecma_IsBooleanValue( ecma_Value_t value) /**< ecma-value */
bool
ecma_IsValueTrue( ecma_Value_t value) /**< ecma-value */
{
JERRY_ASSERT( ecma_IsBooleanValue( value) );
JERRY_ASSERT( ecma_IsValueBoolean( value) );
return ( value.m_ValueType == ECMA_TYPE_SIMPLE && value.m_Value == ECMA_SIMPLE_VALUE_TRUE );
} /* ecma_IsValueTrue */
@ -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_DeallocNumber( 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
*/
@ -131,6 +242,36 @@ ecma_MakeThrowValue( ecma_Object_t *exception_p) /**< an object */
ECMA_TARGET_ID_RESERVED);
} /* ecma_MakeThrowValue */
/**
* Check if the completion value is normal true.
*
* @return true - if the completion type is normal and
* value contains ecma-true simple value,
* false - otherwise.
*/
bool
ecma_IsCompletionValueNormalTrue( ecma_CompletionValue_t value) /**< completion value */
{
return ( value.type == ECMA_COMPLETION_TYPE_NORMAL
&& value.value.m_ValueType == ECMA_TYPE_SIMPLE
&& value.value.m_Value == ECMA_SIMPLE_VALUE_TRUE );
} /* ecma_IsCompletionValueNormalTrue */
/**
* Check if the completion value is normal false.
*
* @return true - if the completion type is normal and
* value contains ecma-false simple value,
* false - otherwise.
*/
bool
ecma_IsCompletionValueNormalFalse( ecma_CompletionValue_t value) /**< completion value */
{
return ( value.type == ECMA_COMPLETION_TYPE_NORMAL
&& value.value.m_ValueType == ECMA_TYPE_SIMPLE
&& value.value.m_Value == ECMA_SIMPLE_VALUE_FALSE );
} /* ecma_IsCompletionValueNormalFalse */
/**
* @}
* @}

View File

@ -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;
@ -395,13 +630,13 @@ ecma_FreeArray( ecma_ArrayFirstChunk_t *pFirstChunk) /**< first chunk of the arr
ecma_ArrayNonFirstChunk_t *pNonFirstChunk = ecma_GetPointer( pFirstChunk->m_Header.m_pNextChunk);
ecma_FreeArrayFirstChunk( pFirstChunk);
ecma_DeallocArrayFirstChunk( pFirstChunk);
while ( pNonFirstChunk != NULL )
{
ecma_ArrayNonFirstChunk_t *pNextChunk = ecma_GetPointer( pNonFirstChunk->m_pNextChunk);
ecma_FreeArrayNonFirstChunk( pNonFirstChunk);
ecma_DeallocArrayNonFirstChunk( pNonFirstChunk);
pNonFirstChunk = pNextChunk;
}

View File

@ -42,16 +42,22 @@ extern void* ecma_DecompressPointer(uintptr_t compressedPointer);
(field) = ecma_CompressPointer( nonCompressedPointer) & ( ( 1u << ECMA_POINTER_FIELD_WIDTH ) - 1)
/* ecma-helpers-value.c */
extern bool ecma_IsUndefinedValue( ecma_Value_t value);
extern bool ecma_IsNullValue( ecma_Value_t value);
extern bool ecma_IsBooleanValue( ecma_Value_t value);
extern bool ecma_IsValueUndefined( ecma_Value_t value);
extern bool ecma_IsValueNull( ecma_Value_t value);
extern bool ecma_IsValueBoolean( ecma_Value_t value);
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);
extern bool ecma_IsCompletionValueNormalFalse( ecma_CompletionValue_t value);
extern bool ecma_IsCompletionValueNormalTrue( ecma_CompletionValue_t value);
extern ecma_Object_t* ecma_CreateObject( ecma_Object_t *pPrototypeObject, bool isExtensible);
extern ecma_Object_t* ecma_CreateLexicalEnvironment( ecma_Object_t *pOuterLexicalEnvironment, ecma_LexicalEnvironmentType_t type);
@ -59,11 +65,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);

View File

@ -18,7 +18,6 @@
*/
#include "ecma-exceptions.h"
#include "ecma-gc.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
#include "ecma-operations.h"
@ -30,49 +29,6 @@
* @{
*/
/**
* Resolve syntactic reference to ECMA-reference.
*
* Warning: string pointed by name_p
* must not be freed or reused
* until the reference is freed.
*
* @return ECMA-reference (if base value is an object, upon return
* it's reference counter is increased by one).
*/
ecma_Reference_t
ecma_OpGetIdentifierReference(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Char_t *name_p, /**< identifier's name */
bool is_strict) /**< strict reference flag */
{
JERRY_ASSERT( lex_env_p != NULL );
ecma_Object_t *lex_env_iter_p = lex_env_p;
while ( lex_env_iter_p != NULL )
{
ecma_CompletionValue_t completion_value;
completion_value = ecma_OpHasBinding( lex_env_iter_p, name_p);
JERRY_ASSERT( completion_value.type == ECMA_COMPLETION_TYPE_NORMAL );
if ( ecma_IsValueTrue( completion_value.value) )
{
ecma_RefObject( lex_env_iter_p);
return (ecma_Reference_t) { .base = ecma_MakeObjectValue( lex_env_iter_p),
.referenced_name_p = name_p,
.is_strict = is_strict };
}
lex_env_iter_p = ecma_GetPointer( lex_env_iter_p->u.m_LexicalEnvironment.m_pOuterReference);
}
return (ecma_Reference_t) { .base = ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_UNDEFINED),
.referenced_name_p = NULL,
.is_strict = is_strict };
} /* ecma_OpGetIdentifierReference */
/**
* GetValue operation.
*
@ -82,28 +38,31 @@ ecma_CompletionValue_t
ecma_OpGetValue( ecma_Reference_t *ref_p) /**< ECMA-reference */
{
const ecma_Value_t base = ref_p->base;
const bool is_unresolvable_reference = ecma_IsUndefinedValue( base);
const bool has_primitive_base = ( ecma_IsBooleanValue( base)
const bool is_unresolvable_reference = ecma_IsValueUndefined( base);
const bool has_primitive_base = ( ecma_IsValueBoolean( base)
|| base.m_ValueType == ECMA_TYPE_NUMBER
|| base.m_ValueType == ECMA_TYPE_STRING );
const bool is_property_reference = has_primitive_base || ( base.m_ValueType == ECMA_TYPE_OBJECT );
// GetValue_3
if ( is_unresolvable_reference )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_REFERENCE));
}
// GetValue_4
if ( is_property_reference )
{
if ( !has_primitive_base )
if ( !has_primitive_base ) // GetValue_4.a
{
ecma_Object_t *obj_p = ecma_GetPointer( base.m_Value);
JERRY_ASSERT( obj_p != NULL && !obj_p->m_IsLexicalEnvironment );
/* return [[Get]]( obj_p as this, ref_p->referenced_name_p) */
// GetValue_4.b case 1
/* return [[Get]]( base as this, ref_p->referenced_name_p) */
JERRY_UNIMPLEMENTED();
} else
{
{ // GetValue_4.b case 2
/*
ecma_Object_t *obj_p = ecma_ToObject( base);
JERRY_ASSERT( obj_p != NULL && !obj_p->m_IsLexicalEnvironment );
@ -126,7 +85,7 @@ ecma_OpGetValue( ecma_Reference_t *ref_p) /**< ECMA-reference */
ECMA_TARGET_ID_RESERVED);
} else
{
[[Call]]( getter, base as this);
return [[Call]]( getter, base as this);
}
}
*/
@ -134,6 +93,7 @@ ecma_OpGetValue( ecma_Reference_t *ref_p) /**< ECMA-reference */
}
} else
{
// GetValue_5
ecma_Object_t *lex_env_p = ecma_GetPointer( base.m_Value);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
@ -151,7 +111,116 @@ ecma_CompletionValue_t
ecma_OpSetValue(ecma_Reference_t *ref_p, /**< ECMA-reference */
ecma_Value_t value) /**< ECMA-value */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( ref_p, value);
const ecma_Value_t base = ref_p->base;
const bool is_unresolvable_reference = ecma_IsValueUndefined( base);
const bool has_primitive_base = ( ecma_IsValueBoolean( base)
|| base.m_ValueType == ECMA_TYPE_NUMBER
|| base.m_ValueType == ECMA_TYPE_STRING );
const bool is_property_reference = has_primitive_base || ( base.m_ValueType == ECMA_TYPE_OBJECT );
if ( is_unresolvable_reference ) // PutValue_3
{
if ( ref_p->is_strict ) // PutValue_3.a
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_REFERENCE));
} else // PutValue_3.b
{
/*
ecma_Object_t *global_object_p = ecma_GetGlobalObject();
return global_object_p->[[Put]]( ref_p->referenced_name_p, value, false);
*/
JERRY_UNIMPLEMENTED();
}
} else if ( is_property_reference ) // PutValue_4
{
if ( !has_primitive_base ) // PutValue_4.a
{
// PutValue_4.b case 1
/* return [[Put]]( base as this, ref_p->referenced_name_p, value, ref_p->is_strict); */
JERRY_UNIMPLEMENTED();
} else
{
// PutValue_4.b case 2
/*
// PutValue_sub_1
ecma_Object_t *obj_p = ecma_ToObject( base);
JERRY_ASSERT( obj_p != NULL && !obj_p->m_IsLexicalEnvironment );
// PutValue_sub_2
if ( !obj_p->[[CanPut]]( ref_p->referenced_name_p) )
{
// PutValue_sub_2.a
if ( ref_p->is_strict )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_TYPE));
} else
{ // PutValue_sub_2.b
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY),
ECMA_TARGET_ID_RESERVED);
}
}
// PutValue_sub_3
ecma_Property_t *own_prop = obj_p->[[GetOwnProperty]]( ref_p->referenced_name_p);
// PutValue_sub_4
if ( ecma_OpIsDataDescriptor( own_prop) )
{
// PutValue_sub_4.a
if ( ref_p->is_strict )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_TYPE));
} else
{ // PutValue_sub_4.b
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY),
ECMA_TARGET_ID_RESERVED);
}
}
// PutValue_sub_5
ecma_Property_t *prop = obj_p->[[GetProperty]]( ref_p->referenced_name_p);
// PutValue_sub_6
if ( ecma_OpIsAccessorDescriptor( prop) )
{
// PutValue_sub_6.a
ecma_Object_t *setter = ecma_GetPointer( property->u.m_NamedAccessorProperty.m_pSet);
JERRY_ASSERT( setter != NULL );
// PutValue_sub_6.b
return [[Call]]( setter, base as this, value);
} else // PutValue_sub_7
{
// PutValue_sub_7.a
if ( ref_p->is_strict )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_TYPE));
}
}
// PutValue_sub_8
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY),
ECMA_TARGET_ID_RESERVED);
*/
JERRY_UNIMPLEMENTED();
}
} else
{
// PutValue_7
ecma_Object_t *lex_env_p = ecma_GetPointer( base.m_Value);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
return ecma_OpSetMutableBinding( lex_env_p, ref_p->referenced_name_p, value, ref_p->is_strict);
}
} /* ecma_OpSetValue */
/**

View File

@ -13,6 +13,7 @@
* limitations under the License.
*/
#include "ecma-exceptions.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
@ -46,7 +47,8 @@ ecma_OpHasBinding(ecma_Object_t *lex_env_p, /**< lexical environment */
{
ecma_Property_t *property_p = ecma_FindNamedProperty( lex_env_p, name_p);
has_binding = ( property_p != NULL ) ? ECMA_SIMPLE_VALUE_TRUE : ECMA_SIMPLE_VALUE_FALSE;
has_binding = ( property_p != NULL ) ? ECMA_SIMPLE_VALUE_TRUE
: ECMA_SIMPLE_VALUE_FALSE;
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
@ -69,7 +71,32 @@ ecma_OpCreateMutableBinding(ecma_Object_t *lex_env_p, /**< lexical environment *
ecma_Char_t *name_p, /**< argument N */
bool is_deletable) /**< argument D */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p, is_deletable);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
JERRY_ASSERT( name_p != NULL );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
JERRY_ASSERT( ecma_IsCompletionValueNormalFalse( ecma_OpHasBinding( lex_env_p, name_p)) );
ecma_CreateNamedProperty( lex_env_p,
name_p,
ECMA_PROPERTY_WRITABLE,
ECMA_PROPERTY_NOT_ENUMERABLE,
is_deletable ? ECMA_PROPERTY_CONFIGURABLE
: ECMA_PROPERTY_NOT_CONFIGURABLE);
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNIMPLEMENTED();
}
}
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY),
ECMA_TARGET_ID_RESERVED);
} /* ecma_OpCreateMutableBinding */
/**
@ -83,7 +110,34 @@ ecma_OpSetMutableBinding(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Value_t value, /**< argument V */
bool is_strict) /**< argument S */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p, value, is_strict);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
JERRY_ASSERT( name_p != NULL );
JERRY_ASSERT( ecma_IsCompletionValueNormalTrue( ecma_OpHasBinding( lex_env_p, name_p)) );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_Property_t *property_p = ecma_GetNamedDataProperty( lex_env_p, name_p);
if ( property_p->u.m_NamedDataProperty.m_Writable == ECMA_PROPERTY_WRITABLE )
{
property_p->u.m_NamedDataProperty.m_Value = value;
} else if ( is_strict )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_TYPE));
}
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNIMPLEMENTED();
}
}
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_EMPTY),
ECMA_TARGET_ID_RESERVED);
} /* ecma_OpSetMutableBinding */
/**
@ -96,7 +150,47 @@ ecma_OpGetBindingValue(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Char_t *name_p, /**< argument N */
bool is_strict) /**< argument S */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p, is_strict);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
JERRY_ASSERT( name_p != NULL );
JERRY_ASSERT( ecma_IsCompletionValueNormalTrue( ecma_OpHasBinding( lex_env_p, name_p)) );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_Property_t *property_p = ecma_GetNamedDataProperty( lex_env_p, name_p);
ecma_Value_t prop_value = property_p->u.m_NamedDataProperty.m_Value;
/* is the binding mutable? */
if ( property_p->u.m_NamedDataProperty.m_Writable == ECMA_PROPERTY_WRITABLE )
{
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
prop_value,
ECMA_TARGET_ID_RESERVED);
} else if ( prop_value.m_ValueType == ECMA_TYPE_SIMPLE
&& prop_value.m_Value == ECMA_SIMPLE_VALUE_EMPTY )
{
/* unitialized immutable binding */
if ( is_strict )
{
return ecma_MakeThrowValue( ecma_NewStandardError( ECMA_ERROR_REFERENCE));
} else
{
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_UNDEFINED),
ECMA_TARGET_ID_RESERVED);
}
}
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNIMPLEMENTED();
}
}
JERRY_UNREACHABLE();
} /* ecma_OpGetBindingValue */
/**
@ -108,7 +202,45 @@ ecma_CompletionValue_t
ecma_OpDeleteBinding(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Char_t *name_p) /**< argument N */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
JERRY_ASSERT( name_p != NULL );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
ecma_Property_t *prop_p = ecma_FindNamedProperty( lex_env_p, name_p);
ecma_SimpleValue_t ret_val;
if ( prop_p == NULL )
{
ret_val = ECMA_SIMPLE_VALUE_TRUE;
} else
{
JERRY_ASSERT( prop_p->m_Type == ECMA_PROPERTY_NAMEDDATA );
if ( prop_p->u.m_NamedDataProperty.m_Configurable == ECMA_PROPERTY_NOT_CONFIGURABLE )
{
ret_val = ECMA_SIMPLE_VALUE_FALSE;
} else
{
ecma_DeleteProperty( lex_env_p, prop_p);
ret_val = ECMA_SIMPLE_VALUE_TRUE;
}
}
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ret_val),
ECMA_TARGET_ID_RESERVED);
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNIMPLEMENTED();
}
}
JERRY_UNREACHABLE();
} /* ecma_OpDeleteBinding */
/**
@ -119,7 +251,23 @@ ecma_OpDeleteBinding(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_CompletionValue_t
ecma_OpImplicitThisValue( ecma_Object_t *lex_env_p) /**< lexical environment */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
return ecma_MakeCompletionValue( ECMA_COMPLETION_TYPE_NORMAL,
ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_UNDEFINED),
ECMA_TARGET_ID_RESERVED);
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNIMPLEMENTED();
}
}
JERRY_UNREACHABLE();
} /* ecma_OpImplicitThisValue */
/**
@ -131,7 +279,35 @@ ecma_CompletionValue_t
ecma_OpCreateImmutableBinding(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Char_t *name_p) /**< argument N */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
JERRY_ASSERT( ecma_IsCompletionValueNormalFalse( ecma_OpHasBinding( lex_env_p, name_p)) );
/*
* Warning:
* Whether immutable bindings are deletable seems not to be defined by ECMA v5.
*/
ecma_Property_t *prop_p = ecma_CreateNamedProperty( lex_env_p,
name_p,
ECMA_PROPERTY_NOT_WRITABLE,
ECMA_PROPERTY_NOT_ENUMERABLE,
ECMA_PROPERTY_NOT_CONFIGURABLE);
JERRY_ASSERT( prop_p->u.m_NamedDataProperty.m_Value.m_ValueType == ECMA_TYPE_SIMPLE );
prop_p->u.m_NamedDataProperty.m_Value.m_Value = ECMA_SIMPLE_VALUE_EMPTY;
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNREACHABLE();
}
}
JERRY_UNREACHABLE();
} /* ecma_OpCreateImmutableBinding */
/**
@ -144,7 +320,30 @@ ecma_OpInitializeImmutableBinding(ecma_Object_t *lex_env_p, /**< lexical environ
ecma_Char_t *name_p, /**< argument N */
ecma_Value_t value) /**< argument V */
{
JERRY_UNIMPLEMENTED_REF_UNUSED_VARS( lex_env_p, name_p, value);
JERRY_ASSERT( lex_env_p != NULL && lex_env_p->m_IsLexicalEnvironment );
switch ( (ecma_LexicalEnvironmentType_t) lex_env_p->u.m_LexicalEnvironment.m_Type )
{
case ECMA_LEXICAL_ENVIRONMENT_DECLARATIVE:
{
JERRY_ASSERT( ecma_IsCompletionValueNormalTrue( ecma_OpHasBinding( lex_env_p, name_p)) );
ecma_Property_t *prop_p = ecma_GetNamedDataProperty( lex_env_p, name_p);
/* The binding must be unitialized immutable binding */
JERRY_ASSERT( prop_p->u.m_NamedDataProperty.m_Writable == ECMA_PROPERTY_NOT_WRITABLE
&& prop_p->u.m_NamedDataProperty.m_Value.m_ValueType == ECMA_TYPE_SIMPLE
&& prop_p->u.m_NamedDataProperty.m_Value.m_Value == ECMA_SIMPLE_VALUE_EMPTY );
prop_p->u.m_NamedDataProperty.m_Value = value;
}
case ECMA_LEXICAL_ENVIRONMENT_OBJECTBOUND:
{
JERRY_UNREACHABLE();
}
}
JERRY_UNREACHABLE();
} /* ecma_OpInitializeImmutableBinding */
/**

View File

@ -0,0 +1,109 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "ecma-gc.h"
#include "ecma-globals.h"
#include "ecma-helpers.h"
#include "ecma-lex-env.h"
#include "ecma-reference.h"
#include "globals.h"
/** \addtogroup ecma ---TODO---
* @{
*/
/**
* \addtogroup references ECMA-Reference
* @{
*/
/**
* Resolve syntactic reference to ECMA-reference.
*
* Warning: string pointed by name_p
* must not be freed or reused
* until the reference is freed.
*
* @return ECMA-reference (if base value is an object, upon return
* it's reference counter is increased by one).
*/
ecma_Reference_t
ecma_OpGetIdentifierReference(ecma_Object_t *lex_env_p, /**< lexical environment */
ecma_Char_t *name_p, /**< identifier's name */
bool is_strict) /**< strict reference flag */
{
JERRY_ASSERT( lex_env_p != NULL );
ecma_Object_t *lex_env_iter_p = lex_env_p;
while ( lex_env_iter_p != NULL )
{
ecma_CompletionValue_t completion_value;
completion_value = ecma_OpHasBinding( lex_env_iter_p, name_p);
if ( ecma_IsCompletionValueNormalTrue( completion_value) )
{
return ecma_MakeReference( ecma_MakeObjectValue( lex_env_iter_p),
name_p,
is_strict);
} else
{
JERRY_ASSERT( ecma_IsCompletionValueNormalFalse( completion_value) );
}
lex_env_iter_p = ecma_GetPointer( lex_env_iter_p->u.m_LexicalEnvironment.m_pOuterReference);
}
return ecma_MakeReference( ecma_MakeSimpleValue( ECMA_SIMPLE_VALUE_UNDEFINED),
name_p,
is_strict);
} /* ecma_OpGetIdentifierReference */
/**
* ECMA-reference constructor.
*
* Warning: string pointed by name_p
* must not be freed or reused
* until the reference is freed.
*
* @return ECMA-reference (if base_p it not NULL, then upon return
* corresponding object's reference counter is increased by one).
*/
ecma_Reference_t
ecma_MakeReference(ecma_Value_t base, /**< base value */
ecma_Char_t *name_p, /**< referenced name */
bool is_strict) /**< strict reference flag */
{
return (ecma_Reference_t) { .base = ecma_CopyValue( base),
.referenced_name_p = name_p,
.is_strict = is_strict };
} /* ecma_MakeReference */
/**
* Free specified ECMA-reference.
*
* Warning:
* after freeing all copy of the reference become invalid.
*/
void
ecma_FreeReference( const ecma_Reference_t ref) /**< reference */
{
ecma_FreeValue( ref.base);
} /* ecma_FreeReference */
/**
* @}
* @}
*/

View File

@ -0,0 +1,40 @@
/* Copyright 2014 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef ECMA_REFERENCE_H
#define ECMA_REFERENCE_H
#include "ecma-globals.h"
#include "globals.h"
/** \addtogroup ecma ---TODO---
* @{
*/
/**
* \addtogroup references ECMA-Reference
* @{
*/
extern ecma_Reference_t ecma_OpGetIdentifierReference(ecma_Object_t *lex_env_p, ecma_Char_t *name_p, bool is_strict);
extern ecma_Reference_t ecma_MakeReference( ecma_Value_t base, ecma_Char_t *name_p, bool is_strict);
extern void ecma_FreeReference( const ecma_Reference_t ref);
/**
* @}
* @}
*/
#endif /* !ECMA_REFERENCE_H */