From c12659ba5198bdc950b2be59ffd185daa152d9fd Mon Sep 17 00:00:00 2001 From: Ruben Ayrapetyan Date: Tue, 3 Feb 2015 18:25:38 +0300 Subject: [PATCH] Introducing managed pointer class ecma_pointer_t, using it to store pointer in ecma_value_t. --- src/libecmaobjects/ecma-compressed-pointers.h | 25 +++- src/libecmaobjects/ecma-globals.h | 129 +++++++++++++++--- src/libecmaobjects/ecma-value.h | 12 +- 3 files changed, 135 insertions(+), 31 deletions(-) diff --git a/src/libecmaobjects/ecma-compressed-pointers.h b/src/libecmaobjects/ecma-compressed-pointers.h index 8eed5c08c..30f2a6804 100644 --- a/src/libecmaobjects/ecma-compressed-pointers.h +++ b/src/libecmaobjects/ecma-compressed-pointers.h @@ -20,8 +20,31 @@ /** \addtogroup ecma ECMA * @{ + */ + +/** \addtogroup compressedpointer Compressed pointer + * @{ + */ + +/** + * Ecma-pointer field is used to calculate ecma-value's address. * - * \addtogroup ecmacompressedpointers Helpers for operations with compressed heap pointers + * Ecma-pointer contains value's shifted offset from common Ecma-pointers' base. + * The offset is shifted right by MEM_ALIGNMENT_LOG. + * Least significant MEM_ALIGNMENT_LOG bits of non-shifted offset are zeroes. + */ +#define ECMA_POINTER_FIELD_WIDTH MEM_COMPRESSED_POINTER_WIDTH + +/** + * The NULL value for compressed pointers + */ +#define ECMA_NULL_POINTER MEM_COMPRESSED_POINTER_NULL + +/** + * @} + */ + +/** \addtogroup ecmacompressedpointers Helpers for operations with compressed heap pointers * @{ */ diff --git a/src/libecmaobjects/ecma-globals.h b/src/libecmaobjects/ecma-globals.h index 0895035d0..74f2dd4f7 100644 --- a/src/libecmaobjects/ecma-globals.h +++ b/src/libecmaobjects/ecma-globals.h @@ -24,31 +24,10 @@ #define JERRY_ECMA_GLOBALS_H #include "config.h" +#include "ecma-compressed-pointers.h" #include "globals.h" #include "mem-allocator.h" -/** \addtogroup compressedpointer Compressed pointer - * @{ - */ - -/** - * Ecma-pointer field is used to calculate ecma-value's address. - * - * Ecma-pointer contains value's shifted offset from common Ecma-pointers' base. - * The offset is shifted right by MEM_ALIGNMENT_LOG. - * Least significant MEM_ALIGNMENT_LOG bits of non-shifted offset are zeroes. - */ -#define ECMA_POINTER_FIELD_WIDTH MEM_COMPRESSED_POINTER_WIDTH - -/** - * The NULL value for compressed pointers - */ -#define ECMA_NULL_POINTER MEM_COMPRESSED_POINTER_NULL - -/** - * @} - */ - /** * Type of ecma-value */ @@ -769,6 +748,112 @@ typedef struct } u; } ecma_string_t; +/** \addtogroup ecmamanagedpointers ECMA managed on-stack pointers + * @{ + */ + +/** + * ECMA managed on-stack pointer + */ +class ecma_pointer_t +{ + public: + /* Constructors */ + __attribute_always_inline__ + ecma_pointer_t () : _ptr (NULL) {} + + ecma_pointer_t (const ecma_pointer_t&) = delete; + ecma_pointer_t (ecma_pointer_t&) = delete; + ecma_pointer_t (ecma_pointer_t&&) = delete; + + /* Getter */ + template + __attribute_always_inline__ + explicit operator T* () const + { + return static_cast (_ptr); + } + + /* Member access */ + template + __attribute_always_inline__ + T* operator -> () const + { + return (T*) _ptr; + } + + /* Dereference */ + template + __attribute_always_inline__ + T operator * () const + { + return *static_cast (_ptr); + } + + /* Assignment operators */ + template + __attribute_always_inline__ + ecma_pointer_t& operator = (T* ptr) /**< new pointer value */ + { + _ptr = ptr; + + return *this; + } + + template + __attribute_always_inline__ + ecma_pointer_t& operator = (const T& value) /**< value to assign to variable + * under the pointer */ + { + *static_cast (_ptr) = value; + + return *this; + } + + __attribute_always_inline__ + ecma_pointer_t& operator = (const ecma_pointer_t& ptr) /**< managed pointer + * to take value from */ + { + _ptr = ptr._ptr; + + return *this; + } + + ecma_pointer_t& operator = (ecma_pointer_t &) = delete; + ecma_pointer_t& operator = (ecma_pointer_t &&) = delete; + + /* Packing to compressed pointer */ + __attribute_always_inline__ + void pack_to (uintptr_t& compressed_pointer) const /**< reference to compressed pointer */ + { + ECMA_SET_NON_NULL_POINTER (compressed_pointer, _ptr); + } + + /* Unpacking from compressed pointer */ + __attribute_always_inline__ + void unpack_from (uintptr_t compressed_pointer) /**< compressed pointer */ + { + _ptr = ECMA_GET_NON_NULL_POINTER (void, compressed_pointer); + } + + protected: /* accessible to ecma_pointer_t */ + void *_ptr; /* pointer storage */ +}; + +#define ECMA_DECLARE_POINTER_OPERATORS_FOR(type) \ + template ecma_pointer_t::operator type* () const; \ + template type* ecma_pointer_t::operator -> () const; \ + template type ecma_pointer_t::operator * () const; \ + template ecma_pointer_t& ecma_pointer_t::operator = (type *); \ + template ecma_pointer_t& ecma_pointer_t::operator = (const type &); + +/** + * ECMA managed pointers' operators explicit instantiation + */ +ECMA_DECLARE_POINTER_OPERATORS_FOR (ecma_number_t) +ECMA_DECLARE_POINTER_OPERATORS_FOR (ecma_string_t) +ECMA_DECLARE_POINTER_OPERATORS_FOR (ecma_object_t) + /** * @} */ diff --git a/src/libecmaobjects/ecma-value.h b/src/libecmaobjects/ecma-value.h index 321c28e58..5cb9c8357 100644 --- a/src/libecmaobjects/ecma-value.h +++ b/src/libecmaobjects/ecma-value.h @@ -112,7 +112,7 @@ class ecma_value_t || _type == ECMA_TYPE_STRING || _type == ECMA_TYPE_OBJECT); - ECMA_SET_NON_NULL_POINTER (value, _value_p); + _value_p.pack_to (value); } return pack (_type, value); @@ -178,7 +178,7 @@ class ecma_value_t || _type == ECMA_TYPE_STRING || _type == ECMA_TYPE_OBJECT); - _value_p = ECMA_GET_NON_NULL_POINTER (void, value); + _value_p.unpack_from (value); } return *this; @@ -320,12 +320,8 @@ class ecma_value_t } ecma_type_t _type; - - union - { - ecma_simple_value_t _simple_value; - void* _value_p; - }; + ecma_simple_value_t _simple_value; + ecma_pointer_t _value_p; }; /**