mirror of
https://github.com/jerryscript-project/jerryscript.git
synced 2025-12-15 16:29:21 +00:00
Merge branch 'master' into geppetto
This commit is contained in:
commit
c53eccbdd6
@ -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)
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
*/
|
||||
|
||||
@ -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 */
|
||||
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
|
||||
@ -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;
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
@ -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 */
|
||||
|
||||
/**
|
||||
|
||||
109
src/libecmaoperations/ecma-reference.c
Normal file
109
src/libecmaoperations/ecma-reference.c
Normal 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 */
|
||||
|
||||
/**
|
||||
* @}
|
||||
* @}
|
||||
*/
|
||||
40
src/libecmaoperations/ecma-reference.h
Normal file
40
src/libecmaoperations/ecma-reference.h
Normal 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 */
|
||||
Loading…
x
Reference in New Issue
Block a user