Replacing ecma_array_first_chunk_t with ecma_string_t for ecma-strings.
This commit is contained in:
@@ -662,7 +662,7 @@ opfunc_assignment (OPCODE opdata, /**< operation data */
|
||||
case OPCODE_ARG_TYPE_STRING:
|
||||
{
|
||||
string_literal_copy str_value;
|
||||
ecma_array_first_chunk_t *ecma_string_p;
|
||||
ecma_string_t *ecma_string_p;
|
||||
|
||||
init_string_literal_copy (src_val_descr, &str_value);
|
||||
ecma_string_p = ecma_new_ecma_string (str_value.str_p);
|
||||
|
||||
@@ -13,25 +13,6 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
/** \addtogroup ecma ---TODO---
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaalloc Routines for allocation/freeing memory for ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of routins for allocation/freeing memory for ECMA data types.
|
||||
*
|
||||
* All allocation routines from this module have the same structure:
|
||||
* 1. Try to allocate memory.
|
||||
* 2. If allocation was successful, return pointer to the allocated block.
|
||||
* 3. Run garbage collection.
|
||||
* 4. Try to allocate memory.
|
||||
* 5. If allocation was successful, return pointer to the allocated block;
|
||||
* else - shutdown engine.
|
||||
*/
|
||||
|
||||
#include "globals.h"
|
||||
#include "ecma-alloc.h"
|
||||
#include "ecma-globals.h"
|
||||
@@ -50,16 +31,32 @@ JERRY_STATIC_ASSERT(sizeof (ecma_array_non_first_chunk_t) == sizeof (uint64_t));
|
||||
JERRY_STATIC_ASSERT(sizeof (ecma_string_t) == sizeof (uint64_t));
|
||||
JERRY_STATIC_ASSERT(sizeof (ecma_completion_value_t) == sizeof (uint32_t));
|
||||
|
||||
/** \addtogroup ecma ---TODO---
|
||||
* @{
|
||||
*
|
||||
* \addtogroup ecmaalloc Routines for allocation/freeing memory for ECMA data types
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Implementation of routines for allocation/freeing memory for ECMA data types.
|
||||
*
|
||||
* All allocation routines from this module have the same structure:
|
||||
* 1. Try to allocate memory.
|
||||
* 2. If allocation was successful, return pointer to the allocated block.
|
||||
* 3. Run garbage collection.
|
||||
* 4. Try to allocate memory.
|
||||
* 5. If allocation was successful, return pointer to the allocated block;
|
||||
* else - shutdown engine.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Template of an allocation routine.
|
||||
*
|
||||
* FIXME: Run GC only if allocation failed.
|
||||
*/
|
||||
#define ALLOC(ecma_type) ecma_ ## ecma_type ## _t * \
|
||||
ecma_alloc_ ## ecma_type (void) \
|
||||
{ \
|
||||
ecma_ ## ecma_type ## _t *p ## ecma_type = (ecma_ ## ecma_type ## _t *) \
|
||||
mem_pools_alloc (); \
|
||||
ecma_ ## ecma_type ## _t *p ## ecma_type = (ecma_ ## ecma_type ## _t *) mem_pools_alloc (); \
|
||||
\
|
||||
if (likely (p ## ecma_type != NULL)) \
|
||||
{ \
|
||||
@@ -72,8 +69,7 @@ JERRY_STATIC_ASSERT(sizeof (ecma_completion_value_t) == sizeof (uint32_t));
|
||||
{ \
|
||||
ecma_gc_run (gen_id); \
|
||||
\
|
||||
p ## ecma_type = (ecma_ ## ecma_type ## _t *) \
|
||||
mem_pools_alloc (); \
|
||||
p ## ecma_type = (ecma_ ## ecma_type ## _t *) mem_pools_alloc (); \
|
||||
\
|
||||
if (likely (p ## ecma_type != NULL)) \
|
||||
{ \
|
||||
@@ -104,6 +100,7 @@ DECLARE_ROUTINES_FOR (property)
|
||||
DECLARE_ROUTINES_FOR (number)
|
||||
DECLARE_ROUTINES_FOR (array_first_chunk)
|
||||
DECLARE_ROUTINES_FOR (array_non_first_chunk)
|
||||
DECLARE_ROUTINES_FOR (string)
|
||||
|
||||
/**
|
||||
* @}
|
||||
|
||||
@@ -83,7 +83,19 @@ extern ecma_array_non_first_chunk_t *ecma_alloc_array_non_first_chunk (void);
|
||||
/**
|
||||
* Dealloc memory from non-first chunk of an ecma-array
|
||||
*/
|
||||
extern void ecma_dealloc_array_non_first_chunk (ecma_array_non_first_chunk_t *number_p);
|
||||
extern void ecma_dealloc_array_non_first_chunk (ecma_array_non_first_chunk_t *non_first_chunk_p);
|
||||
|
||||
/**
|
||||
* Allocate memory for ecma-string descriptor
|
||||
*
|
||||
* @return pointer to allocated memory
|
||||
*/
|
||||
extern ecma_string_t *ecma_alloc_string (void);
|
||||
|
||||
/**
|
||||
* Dealloc memory from ecma-string descriptor
|
||||
*/
|
||||
extern void ecma_dealloc_string (ecma_string_t *string_p);
|
||||
|
||||
#endif /* JERRY_ECMA_ALLOC_H */
|
||||
|
||||
|
||||
@@ -491,7 +491,7 @@ typedef uint16_t ecma_length_t;
|
||||
typedef struct
|
||||
{
|
||||
/** Compressed pointer to next chunk */
|
||||
uint16_t next_chunk_p;
|
||||
uint16_t next_chunk_cp;
|
||||
|
||||
/** Number of elements in the Array */
|
||||
ecma_length_t unit_number;
|
||||
@@ -515,7 +515,7 @@ typedef struct
|
||||
typedef struct
|
||||
{
|
||||
/** Compressed pointer to next chunk */
|
||||
uint16_t next_chunk_p;
|
||||
uint16_t next_chunk_cp;
|
||||
|
||||
/** Characters */
|
||||
uint8_t data[ sizeof (uint64_t) - sizeof (uint16_t) ];
|
||||
|
||||
@@ -29,140 +29,196 @@
|
||||
/**
|
||||
* Allocate new ecma-string and fill it with characters from specified buffer
|
||||
*
|
||||
* @return Pointer to first chunk of an array, containing allocated string
|
||||
* @return pointer to ecma-string descriptor
|
||||
*/
|
||||
ecma_array_first_chunk_t*
|
||||
ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string of ecma-characters */
|
||||
ecma_string_t*
|
||||
ecma_new_ecma_string (const ecma_char_t *string_p) /**< zero-terminated string */
|
||||
{
|
||||
ecma_length_t length = 0;
|
||||
JERRY_ASSERT (string_p != NULL);
|
||||
|
||||
/*
|
||||
* TODO: Do not precalculate length.
|
||||
*/
|
||||
if (string_p != NULL)
|
||||
ecma_length_t length = 0;
|
||||
const ecma_char_t *iter_p = string_p;
|
||||
|
||||
while (*iter_p++)
|
||||
{
|
||||
const ecma_char_t *iter_p = string_p;
|
||||
while (*iter_p++)
|
||||
{
|
||||
length++;
|
||||
}
|
||||
length++;
|
||||
}
|
||||
|
||||
ecma_array_first_chunk_t *string_first_chunk_p = ecma_alloc_array_first_chunk ();
|
||||
const size_t bytes_needed_for_current_string = sizeof (ecma_char_t) * length;
|
||||
const size_t bytes_for_chars_in_string_descriptor = JERRY_SIZE_OF_STRUCT_MEMBER (ecma_string_t, u.chars);
|
||||
JERRY_STATIC_ASSERT (bytes_for_chars_in_string_descriptor % sizeof (ecma_char_t) == 0);
|
||||
|
||||
string_first_chunk_p->header.unit_number = length;
|
||||
uint8_t *copy_pointer = (uint8_t*) string_p;
|
||||
size_t chars_left = length;
|
||||
size_t chars_to_copy = JERRY_MIN(length, sizeof (string_first_chunk_p->data) / sizeof (ecma_char_t));
|
||||
__memcpy (string_first_chunk_p->data, copy_pointer, chars_to_copy * sizeof (ecma_char_t));
|
||||
chars_left -= chars_to_copy;
|
||||
copy_pointer += chars_to_copy * sizeof (ecma_char_t);
|
||||
ecma_string_t* string_desc_p = ecma_alloc_string ();
|
||||
string_desc_p->refs = 1;
|
||||
string_desc_p->length = length;
|
||||
|
||||
ecma_array_non_first_chunk_t *string_non_first_chunk_p;
|
||||
if (bytes_needed_for_current_string <= bytes_for_chars_in_string_descriptor)
|
||||
{
|
||||
string_desc_p->container = ECMA_STRING_CONTAINER_IN_DESCRIPTOR;
|
||||
__memcpy (string_desc_p->u.chars, string_p, bytes_needed_for_current_string);
|
||||
|
||||
JERRY_STATIC_ASSERT(ECMA_POINTER_FIELD_WIDTH <= sizeof (uint16_t) * JERRY_BITSINBYTE);
|
||||
uint16_t *next_chunk_compressed_pointer_p = &string_first_chunk_p->header.next_chunk_p;
|
||||
return string_desc_p;
|
||||
}
|
||||
|
||||
string_desc_p->container = ECMA_STRING_CONTAINER_HEAP;
|
||||
|
||||
const ecma_char_t* src_p = string_p;
|
||||
|
||||
ecma_length_t chars_left = length;
|
||||
JERRY_ASSERT (chars_left > 0);
|
||||
|
||||
ecma_array_non_first_chunk_t *string_chunk_p = ecma_alloc_array_non_first_chunk ();
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER (string_desc_p->u.chunk_cp, string_chunk_p);
|
||||
|
||||
const ecma_length_t max_chars_in_chunk = sizeof (string_chunk_p->data) / sizeof (ecma_char_t);
|
||||
while (chars_left > 0)
|
||||
{
|
||||
string_non_first_chunk_p = ecma_alloc_array_non_first_chunk ();
|
||||
ecma_length_t chars_to_copy = JERRY_MIN(chars_left, max_chars_in_chunk);
|
||||
|
||||
size_t chars_to_copy = JERRY_MIN(chars_left, sizeof (string_non_first_chunk_p->data) / sizeof (ecma_char_t));
|
||||
__memcpy (string_non_first_chunk_p->data, copy_pointer, chars_to_copy * sizeof (ecma_char_t));
|
||||
chars_left -= chars_to_copy;
|
||||
copy_pointer += chars_to_copy * sizeof (ecma_char_t);
|
||||
__memcpy (string_chunk_p->data, src_p, chars_to_copy * sizeof (ecma_char_t));
|
||||
chars_left = (ecma_length_t) (chars_left - chars_to_copy);
|
||||
src_p += chars_to_copy;
|
||||
|
||||
ECMA_SET_NON_NULL_POINTER(*next_chunk_compressed_pointer_p, string_non_first_chunk_p);
|
||||
next_chunk_compressed_pointer_p = &string_non_first_chunk_p->next_chunk_p;
|
||||
ecma_array_non_first_chunk_t* next_string_chunk_p = ecma_alloc_array_non_first_chunk ();
|
||||
ECMA_SET_NON_NULL_POINTER (string_chunk_p->next_chunk_cp, next_string_chunk_p);
|
||||
string_chunk_p = next_string_chunk_p;
|
||||
}
|
||||
|
||||
*next_chunk_compressed_pointer_p = ECMA_NULL_POINTER;
|
||||
string_chunk_p->next_chunk_cp = ECMA_NULL_POINTER;
|
||||
|
||||
return string_first_chunk_p;
|
||||
return string_desc_p;
|
||||
} /* ecma_new_ecma_string */
|
||||
|
||||
/**
|
||||
* Decrease reference counter and deallocate ecma-string if
|
||||
* after that the counter the counter becomes zero.
|
||||
*/
|
||||
void
|
||||
ecma_free_string (ecma_string_t *string_p) /**< ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (string_p != NULL);
|
||||
JERRY_ASSERT (string_p->refs != 0);
|
||||
|
||||
string_p->refs--;
|
||||
|
||||
if (string_p->refs != 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (string_p->container == ECMA_STRING_CONTAINER_HEAP)
|
||||
{
|
||||
ecma_array_non_first_chunk_t *chunk_p = ECMA_GET_POINTER (string_p->u.chunk_cp);
|
||||
|
||||
JERRY_ASSERT (chunk_p != NULL);
|
||||
|
||||
while (chunk_p != NULL)
|
||||
{
|
||||
ecma_array_non_first_chunk_t *next_chunk_p = ECMA_GET_POINTER (chunk_p->next_chunk_cp);
|
||||
|
||||
ecma_dealloc_array_non_first_chunk (chunk_p);
|
||||
|
||||
chunk_p = next_chunk_p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (string_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR
|
||||
|| string_p->container == ECMA_STRING_CONTAINER_LIT_TABLE);
|
||||
|
||||
/* only the string descriptor itself should be freed */
|
||||
}
|
||||
|
||||
ecma_dealloc_string (string_p);
|
||||
} /* ecma_free_string */
|
||||
|
||||
/**
|
||||
* Copy ecma-string's contents to a buffer.
|
||||
*
|
||||
* Buffer will contain length of string, in characters, followed by string's characters.
|
||||
*
|
||||
* @return number of bytes, actually copied to the buffer, if string's content was copied successfully;
|
||||
* negative number, which is calculated as negation of buffer size, that is required
|
||||
* to hold the string's content (in case size of buffer is insuficcient).
|
||||
* @return number of bytes, actually copied to the buffer - if string's content was copied successfully;
|
||||
* otherwise (in case size of buffer is insuficcient) - negative number, which is calculated
|
||||
* as negation of buffer size, that is required to hold the string's content.
|
||||
*/
|
||||
ssize_t
|
||||
ecma_copy_ecma_string_chars_to_buffer (ecma_array_first_chunk_t *first_chunk_p, /**< first chunk of ecma-string */
|
||||
uint8_t *buffer_p, /**< destination buffer */
|
||||
size_t buffer_size) /**< size of buffer */
|
||||
ecma_string_to_zt_string (ecma_string_t *string_desc_p, /**< ecma-string descriptor */
|
||||
ecma_char_t *buffer_p, /**< destination buffer */
|
||||
size_t buffer_size) /**< size of buffer */
|
||||
{
|
||||
ecma_length_t string_length = first_chunk_p->header.unit_number;
|
||||
size_t required_buffer_size = sizeof (ecma_length_t) + sizeof (ecma_char_t) * string_length;
|
||||
JERRY_ASSERT (string_desc_p != NULL);
|
||||
JERRY_ASSERT (string_desc_p->refs > 0);
|
||||
JERRY_ASSERT (buffer_p != NULL);
|
||||
JERRY_ASSERT (buffer_size > 0);
|
||||
|
||||
const ecma_length_t string_length = string_desc_p->length;
|
||||
size_t required_buffer_size = sizeof (ecma_char_t) * string_length + 1 /* for zero char */;
|
||||
|
||||
if (required_buffer_size > buffer_size)
|
||||
{
|
||||
return - (ssize_t) required_buffer_size;
|
||||
}
|
||||
|
||||
*(ecma_length_t*) buffer_p = string_length;
|
||||
ecma_char_t *dest_p = buffer_p;
|
||||
|
||||
size_t chars_left = string_length;
|
||||
uint8_t *dest_pointer = buffer_p + sizeof (ecma_length_t);
|
||||
size_t copy_chunk_chars = JERRY_MIN(sizeof (first_chunk_p->data) / sizeof (ecma_char_t),
|
||||
chars_left);
|
||||
__memcpy (dest_pointer, first_chunk_p->data, copy_chunk_chars * sizeof (ecma_char_t));
|
||||
dest_pointer += copy_chunk_chars * sizeof (ecma_char_t);
|
||||
chars_left -= copy_chunk_chars;
|
||||
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_p = ECMA_GET_POINTER(first_chunk_p->header.next_chunk_p);
|
||||
|
||||
while (chars_left > 0)
|
||||
switch ((ecma_string_container_t)string_desc_p->container)
|
||||
{
|
||||
JERRY_ASSERT(chars_left < string_length);
|
||||
case ECMA_STRING_CONTAINER_IN_DESCRIPTOR:
|
||||
{
|
||||
__memcpy (dest_p, string_desc_p->u.chars, string_length * sizeof (ecma_char_t));
|
||||
dest_p += string_length;
|
||||
|
||||
copy_chunk_chars = JERRY_MIN(sizeof (non_first_chunk_p->data) / sizeof (ecma_char_t),
|
||||
chars_left);
|
||||
__memcpy (dest_pointer, non_first_chunk_p->data, copy_chunk_chars * sizeof (ecma_char_t));
|
||||
dest_pointer += copy_chunk_chars * sizeof (ecma_char_t);
|
||||
chars_left -= copy_chunk_chars;
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_HEAP:
|
||||
{
|
||||
ecma_array_non_first_chunk_t *string_chunk_p = ECMA_GET_POINTER(string_desc_p->u.chunk_cp);
|
||||
|
||||
non_first_chunk_p = ECMA_GET_POINTER(non_first_chunk_p->next_chunk_p);
|
||||
const ecma_length_t max_chars_in_chunk = sizeof (string_chunk_p->data) / sizeof (ecma_char_t);
|
||||
|
||||
ecma_length_t chars_left = string_length;
|
||||
while (chars_left > 0)
|
||||
{
|
||||
JERRY_ASSERT(chars_left < string_length);
|
||||
|
||||
ecma_length_t chars_to_copy = JERRY_MIN(max_chars_in_chunk, chars_left);
|
||||
|
||||
__memcpy (dest_p, string_chunk_p->data, chars_to_copy * sizeof (ecma_char_t));
|
||||
dest_p += chars_to_copy;
|
||||
chars_left = (ecma_length_t) (chars_left - chars_to_copy);
|
||||
|
||||
string_chunk_p = ECMA_GET_POINTER(string_chunk_p->next_chunk_cp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ECMA_STRING_CONTAINER_LIT_TABLE:
|
||||
{
|
||||
JERRY_UNIMPLEMENTED();
|
||||
}
|
||||
}
|
||||
|
||||
*dest_p = '\0';
|
||||
|
||||
return (ssize_t) required_buffer_size;
|
||||
} /* ecma_copy_ecma_string_chars_to_buffer */
|
||||
} /* ecma_string_to_zt_string */
|
||||
|
||||
/**
|
||||
* Duplicate an ecma-string.
|
||||
* Increase reference counter of ecma-string.
|
||||
*
|
||||
* @return pointer to new ecma-string's first chunk
|
||||
* @return pointer to same ecma-string descriptor with increased reference counter
|
||||
*/
|
||||
ecma_array_first_chunk_t*
|
||||
ecma_duplicate_ecma_string (ecma_array_first_chunk_t *first_chunk_p) /**< first chunk of string to duplicate */
|
||||
void
|
||||
ecma_ref_ecma_string (ecma_string_t *string_desc_p) /**< string descriptor */
|
||||
{
|
||||
JERRY_ASSERT(first_chunk_p != NULL);
|
||||
JERRY_ASSERT (string_desc_p != NULL);
|
||||
JERRY_ASSERT (string_desc_p->refs > 0);
|
||||
|
||||
ecma_array_first_chunk_t *first_chunk_copy_p = ecma_alloc_array_first_chunk ();
|
||||
__memcpy (first_chunk_copy_p, first_chunk_p, sizeof (ecma_array_first_chunk_t));
|
||||
string_desc_p->refs++;
|
||||
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_p, *non_first_chunk_copy_p;
|
||||
non_first_chunk_p = ECMA_GET_POINTER(first_chunk_p->header.next_chunk_p);
|
||||
uint16_t *next_pointer_p = &first_chunk_copy_p->header.next_chunk_p;
|
||||
|
||||
while (non_first_chunk_p != NULL)
|
||||
{
|
||||
non_first_chunk_copy_p = ecma_alloc_array_non_first_chunk ();
|
||||
ECMA_SET_POINTER(*next_pointer_p, non_first_chunk_copy_p);
|
||||
next_pointer_p = &non_first_chunk_copy_p->next_chunk_p;
|
||||
|
||||
__memcpy (non_first_chunk_copy_p, non_first_chunk_p, sizeof (ecma_array_non_first_chunk_t));
|
||||
|
||||
non_first_chunk_p = ECMA_GET_POINTER(non_first_chunk_p->next_chunk_p);
|
||||
}
|
||||
|
||||
*next_pointer_p = ECMA_NULL_POINTER;
|
||||
|
||||
return first_chunk_copy_p;
|
||||
} /* ecma_duplicate_ecma_string */
|
||||
/* Check for overflow */
|
||||
JERRY_ASSERT (string_desc_p->refs > 0);
|
||||
} /* ecma_ref_ecma_string */
|
||||
|
||||
/**
|
||||
* Compare ecma-string to ecma-string
|
||||
@@ -171,29 +227,78 @@ ecma_duplicate_ecma_string (ecma_array_first_chunk_t *first_chunk_p) /**< first
|
||||
* false - otherwise.
|
||||
*/
|
||||
bool
|
||||
ecma_compare_ecma_string_to_ecma_string (const ecma_array_first_chunk_t *string1_p, /* ecma-string */
|
||||
const ecma_array_first_chunk_t *string2_p) /* ecma-string */
|
||||
ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p, /* ecma-string */
|
||||
const ecma_string_t *string2_p) /* ecma-string */
|
||||
{
|
||||
JERRY_ASSERT (string1_p != NULL && string2_p != NULL);
|
||||
|
||||
if (string1_p->header.unit_number != string2_p->header.unit_number)
|
||||
if (string1_p == string2_p)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
if (string1_p->length != string2_p->length)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
ecma_length_t chars_left = string1_p->header.unit_number;
|
||||
ecma_length_t chars_left = string1_p->length;
|
||||
|
||||
JERRY_STATIC_ASSERT (ECMA_POINTER_FIELD_WIDTH <= sizeof (uint16_t) * JERRY_BITSINBYTE);
|
||||
const uint16_t *next_chunk_compressed_pointer_1_p = &string1_p->header.next_chunk_p;
|
||||
const uint16_t *next_chunk_compressed_pointer_2_p = &string2_p->header.next_chunk_p;
|
||||
const ecma_char_t *cur_char_array_1_p = string1_p->data;
|
||||
const ecma_char_t *cur_char_array_1_end_p = string1_p->data + sizeof (string1_p->data);
|
||||
const ecma_char_t *cur_char_array_2_p = string2_p->data;
|
||||
const ecma_char_t *cur_char_array_2_end_p = string2_p->data + sizeof (string2_p->data);
|
||||
if (string1_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR
|
||||
&& string2_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
|
||||
{
|
||||
return __memcmp (string1_p->u.chars, string2_p->u.chars, chars_left * sizeof (ecma_char_t));
|
||||
}
|
||||
|
||||
if (string1_p->container == ECMA_STRING_CONTAINER_LIT_TABLE
|
||||
|| string2_p->container == ECMA_STRING_CONTAINER_LIT_TABLE)
|
||||
{
|
||||
JERRY_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
if (string1_p->container == ECMA_STRING_CONTAINER_HEAP
|
||||
&& string2_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
|
||||
{
|
||||
const ecma_string_t *tmp_string_p = string1_p;
|
||||
string1_p = string2_p;
|
||||
string2_p = tmp_string_p;
|
||||
}
|
||||
JERRY_ASSERT (string2_p->container == ECMA_STRING_CONTAINER_HEAP);
|
||||
|
||||
ecma_array_non_first_chunk_t *string1_chunk_p, *string2_chunk_p;
|
||||
const ecma_char_t *cur_char_array_1_p, *cur_char_array_2_p;
|
||||
const ecma_char_t *cur_char_array_1_end_p, *cur_char_array_2_end_p;
|
||||
if (string1_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
|
||||
{
|
||||
string1_chunk_p = NULL;
|
||||
cur_char_array_1_p = string1_p->u.chars;
|
||||
cur_char_array_1_end_p = cur_char_array_1_p + sizeof (string1_p->u.chars) / sizeof (ecma_char_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
string1_chunk_p = ECMA_GET_POINTER (string1_p->u.chunk_cp);
|
||||
cur_char_array_1_p = string1_chunk_p->data;
|
||||
cur_char_array_1_end_p = cur_char_array_1_p + sizeof (string1_chunk_p->data) / sizeof (ecma_char_t);
|
||||
}
|
||||
|
||||
string2_chunk_p = ECMA_GET_POINTER (string2_p->u.chunk_cp);
|
||||
cur_char_array_2_p = string2_chunk_p->data;
|
||||
cur_char_array_2_end_p = cur_char_array_2_p + sizeof (string2_chunk_p->data) / sizeof (ecma_char_t);
|
||||
|
||||
/*
|
||||
* The assertion check allows to combine update of cur_char_array_1_p and cur_char_array_2_p pointers,
|
||||
* because:
|
||||
* - if we reached end of string in descriptor then we reached end of string => chars_left is zero;
|
||||
* - if we reached end of string chunk in heap then we reached end of other string's chunk too
|
||||
* (they're lengths are equal) => both pointer should be updated.
|
||||
*/
|
||||
JERRY_STATIC_ASSERT (sizeof (string1_p->u.chars) / sizeof (ecma_char_t)
|
||||
< sizeof (string1_chunk_p->data) / sizeof (ecma_char_t));
|
||||
|
||||
while (chars_left > 0)
|
||||
{
|
||||
if (cur_char_array_1_p != cur_char_array_1_end_p)
|
||||
if (cur_char_array_1_p != cur_char_array_1_end_p
|
||||
&& cur_char_array_2_p != cur_char_array_2_end_p)
|
||||
{
|
||||
JERRY_ASSERT (cur_char_array_2_p < cur_char_array_2_end_p);
|
||||
|
||||
@@ -203,18 +308,25 @@ ecma_compare_ecma_string_to_ecma_string (const ecma_array_first_chunk_t *string1
|
||||
}
|
||||
|
||||
chars_left--;
|
||||
|
||||
continue;
|
||||
}
|
||||
else
|
||||
|
||||
if (cur_char_array_1_p == cur_char_array_1_end_p)
|
||||
{
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_1_p = ECMA_GET_POINTER (*next_chunk_compressed_pointer_1_p);
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_2_p = ECMA_GET_POINTER (*next_chunk_compressed_pointer_2_p);
|
||||
JERRY_ASSERT (string1_p->container == ECMA_STRING_CONTAINER_HEAP
|
||||
&& string2_p->container == ECMA_STRING_CONTAINER_HEAP);
|
||||
JERRY_ASSERT (cur_char_array_2_p == cur_char_array_2_end_p);
|
||||
|
||||
JERRY_ASSERT (non_first_chunk_1_p != NULL && non_first_chunk_2_p != NULL);
|
||||
string1_chunk_p = ECMA_GET_POINTER (string1_chunk_p->next_chunk_cp);
|
||||
JERRY_ASSERT (string1_chunk_p != NULL);
|
||||
cur_char_array_1_p = string1_chunk_p->data;
|
||||
cur_char_array_1_end_p = cur_char_array_1_p + sizeof (string1_chunk_p->data) / sizeof (ecma_char_t);
|
||||
|
||||
cur_char_array_1_p = non_first_chunk_1_p->data;
|
||||
cur_char_array_1_end_p = non_first_chunk_1_p->data + sizeof (non_first_chunk_1_p->data);
|
||||
cur_char_array_2_p = non_first_chunk_2_p->data;
|
||||
cur_char_array_2_end_p = non_first_chunk_2_p->data + sizeof (non_first_chunk_2_p->data);
|
||||
string2_chunk_p = ECMA_GET_POINTER (string2_chunk_p->next_chunk_cp);
|
||||
JERRY_ASSERT (string2_chunk_p != NULL);
|
||||
cur_char_array_2_p = string2_chunk_p->data;
|
||||
cur_char_array_2_end_p = cur_char_array_2_p + sizeof (string2_chunk_p->data) / sizeof (ecma_char_t);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,19 +357,34 @@ ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, /**< zero-ter
|
||||
*/
|
||||
bool
|
||||
ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-terminated string */
|
||||
const ecma_array_first_chunk_t *ecma_string_p) /* ecma-string */
|
||||
const ecma_string_t *ecma_string_p) /* ecma-string */
|
||||
{
|
||||
JERRY_ASSERT(string_p != NULL);
|
||||
JERRY_ASSERT(ecma_string_p != NULL);
|
||||
|
||||
const ecma_char_t *str_iter_p = string_p;
|
||||
ecma_length_t ecma_str_len = ecma_string_p->header.unit_number;
|
||||
const ecma_char_t *current_chunk_chars_cur = (const ecma_char_t*) ecma_string_p->data;
|
||||
const ecma_char_t *current_chunk_chars_end = (const ecma_char_t*) (ecma_string_p->data +
|
||||
sizeof (ecma_string_p->data));
|
||||
ecma_length_t ecma_str_len = ecma_string_p->length;
|
||||
const ecma_char_t *current_chunk_chars_cur;
|
||||
const ecma_char_t *current_chunk_chars_end;
|
||||
ecma_array_non_first_chunk_t *string_chunk_p = NULL;
|
||||
|
||||
JERRY_STATIC_ASSERT(ECMA_POINTER_FIELD_WIDTH <= sizeof (uint16_t) * JERRY_BITSINBYTE);
|
||||
const uint16_t *next_chunk_compressed_pointer_p = &ecma_string_p->header.next_chunk_p;
|
||||
if (ecma_string_p->container == ECMA_STRING_CONTAINER_IN_DESCRIPTOR)
|
||||
{
|
||||
current_chunk_chars_cur = ecma_string_p->u.chars;
|
||||
current_chunk_chars_end = current_chunk_chars_cur + sizeof (ecma_string_p->u.chars) / sizeof (ecma_char_t);
|
||||
}
|
||||
else if (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP)
|
||||
{
|
||||
string_chunk_p = ECMA_GET_POINTER (ecma_string_p->u.chunk_cp);
|
||||
current_chunk_chars_cur = string_chunk_p->data;
|
||||
current_chunk_chars_end = current_chunk_chars_cur + sizeof (string_chunk_p->data) / sizeof (ecma_char_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_LIT_TABLE);
|
||||
|
||||
JERRY_UNIMPLEMENTED();
|
||||
}
|
||||
|
||||
for (ecma_length_t str_index = 0;
|
||||
str_index < ecma_str_len;
|
||||
@@ -267,15 +394,15 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te
|
||||
|
||||
if (current_chunk_chars_cur == current_chunk_chars_end)
|
||||
{
|
||||
JERRY_ASSERT (ecma_string_p->container == ECMA_STRING_CONTAINER_HEAP);
|
||||
|
||||
/* switching to next chunk */
|
||||
ecma_array_non_first_chunk_t *next_chunk_p = ECMA_GET_POINTER(*next_chunk_compressed_pointer_p);
|
||||
string_chunk_p = ECMA_GET_POINTER (string_chunk_p->next_chunk_cp);
|
||||
|
||||
JERRY_ASSERT(next_chunk_p != NULL);
|
||||
JERRY_ASSERT(string_chunk_p != NULL);
|
||||
|
||||
current_chunk_chars_cur = (const ecma_char_t*) next_chunk_p->data;
|
||||
current_chunk_chars_end = (const ecma_char_t*) (next_chunk_p->data + sizeof (next_chunk_p->data));
|
||||
|
||||
next_chunk_compressed_pointer_p = &next_chunk_p->next_chunk_p;
|
||||
current_chunk_chars_cur = string_chunk_p->data;
|
||||
current_chunk_chars_end = current_chunk_chars_cur + sizeof (string_chunk_p->data) / sizeof (ecma_char_t);
|
||||
}
|
||||
|
||||
if (*str_iter_p != *current_chunk_chars_cur)
|
||||
@@ -296,7 +423,7 @@ ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p, /**< zero-te
|
||||
* If we have also reached end of zero-terminated string, than strings are equal.
|
||||
* Otherwise zero-terminated string is longer.
|
||||
*/
|
||||
return (*str_iter_p == 0);
|
||||
return (*str_iter_p == '\0');
|
||||
} /* ecma_compare_zt_string_to_ecma_string */
|
||||
|
||||
/**
|
||||
|
||||
@@ -127,7 +127,7 @@ ecma_make_number_value (ecma_number_t* num_p) /**< number to reference in value
|
||||
* String value constructor
|
||||
*/
|
||||
ecma_value_t
|
||||
ecma_make_string_value (ecma_array_first_chunk_t* ecma_string_p) /**< string to reference in value */
|
||||
ecma_make_string_value (ecma_string_t* ecma_string_p) /**< string to reference in value */
|
||||
{
|
||||
JERRY_ASSERT(ecma_string_p != NULL);
|
||||
|
||||
@@ -209,16 +209,16 @@ ecma_copy_value (const ecma_value_t value, /**< ecma-value */
|
||||
}
|
||||
case ECMA_TYPE_STRING:
|
||||
{
|
||||
ecma_array_first_chunk_t *string_p = ECMA_GET_POINTER(value.value);
|
||||
ecma_string_t *string_p = ECMA_GET_POINTER(value.value);
|
||||
JERRY_ASSERT(string_p != NULL);
|
||||
|
||||
ecma_array_first_chunk_t *string_copy_p = ecma_duplicate_ecma_string (string_p);
|
||||
ecma_ref_ecma_string (string_p);
|
||||
|
||||
value_copy = (ecma_value_t)
|
||||
{
|
||||
.value_type = ECMA_TYPE_STRING
|
||||
};
|
||||
ECMA_SET_POINTER(value_copy.value, string_copy_p);
|
||||
ECMA_SET_POINTER(value_copy.value, string_p);
|
||||
|
||||
break;
|
||||
}
|
||||
@@ -270,8 +270,8 @@ ecma_free_value (ecma_value_t value, /**< value description */
|
||||
|
||||
case ECMA_TYPE_STRING:
|
||||
{
|
||||
ecma_array_first_chunk_t *string_p = ECMA_GET_POINTER(value.value);
|
||||
ecma_free_array (string_p);
|
||||
ecma_string_t *string_p = ECMA_GET_POINTER(value.value);
|
||||
ecma_free_string (string_p);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ ecma_find_named_property (ecma_object_t *obj_p, /**< object to find property in
|
||||
property_p != NULL;
|
||||
property_p = ECMA_GET_POINTER(property_p->next_property_p))
|
||||
{
|
||||
ecma_array_first_chunk_t *property_name_p;
|
||||
ecma_string_t *property_name_p;
|
||||
|
||||
if (property_p->type == ECMA_PROPERTY_NAMEDDATA)
|
||||
{
|
||||
@@ -361,7 +361,7 @@ ecma_free_named_data_property (ecma_property_t *property_p) /**< the property */
|
||||
{
|
||||
JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDDATA);
|
||||
|
||||
ecma_free_array (ECMA_GET_POINTER(property_p->u.named_data_property.name_p));
|
||||
ecma_free_string (ECMA_GET_POINTER (property_p->u.named_data_property.name_p));
|
||||
ecma_free_value (property_p->u.named_data_property.value, false);
|
||||
|
||||
ecma_dealloc_property (property_p);
|
||||
@@ -375,7 +375,7 @@ ecma_free_named_accessor_property (ecma_property_t *property_p) /**< the propert
|
||||
{
|
||||
JERRY_ASSERT(property_p->type == ECMA_PROPERTY_NAMEDACCESSOR);
|
||||
|
||||
ecma_free_array (ECMA_GET_POINTER(property_p->u.named_accessor_property.name_p));
|
||||
ecma_free_string (ECMA_GET_POINTER (property_p->u.named_accessor_property.name_p));
|
||||
|
||||
ecma_dealloc_property (property_p);
|
||||
} /* ecma_free_named_accessor_property */
|
||||
@@ -490,13 +490,13 @@ ecma_free_array (ecma_array_first_chunk_t *first_chunk_p) /**< first chunk of th
|
||||
{
|
||||
JERRY_ASSERT(first_chunk_p != NULL);
|
||||
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_p = ECMA_GET_POINTER(first_chunk_p->header.next_chunk_p);
|
||||
ecma_array_non_first_chunk_t *non_first_chunk_p = ECMA_GET_POINTER (first_chunk_p->header.next_chunk_cp);
|
||||
|
||||
ecma_dealloc_array_first_chunk (first_chunk_p);
|
||||
|
||||
while (non_first_chunk_p != NULL)
|
||||
{
|
||||
ecma_array_non_first_chunk_t *next_chunk_p = ECMA_GET_POINTER(non_first_chunk_p->next_chunk_p);
|
||||
ecma_array_non_first_chunk_t *next_chunk_p = ECMA_GET_POINTER (non_first_chunk_p->next_chunk_cp);
|
||||
|
||||
ecma_dealloc_array_non_first_chunk (non_first_chunk_p);
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ extern bool ecma_is_value_true (ecma_value_t value);
|
||||
|
||||
extern ecma_value_t ecma_make_simple_value (ecma_simple_value_t value);
|
||||
extern ecma_value_t ecma_make_number_value (ecma_number_t* num_p);
|
||||
extern ecma_value_t ecma_make_string_value (ecma_array_first_chunk_t* ecma_string_p);
|
||||
extern ecma_value_t ecma_make_string_value (ecma_string_t* ecma_string_p);
|
||||
extern ecma_value_t ecma_make_object_value (ecma_object_t* object_p);
|
||||
extern ecma_value_t ecma_copy_value (const ecma_value_t value, bool do_ref_if_object);
|
||||
extern void ecma_free_value (const ecma_value_t value, bool do_deref_if_object);
|
||||
@@ -85,6 +85,19 @@ extern bool ecma_is_completion_value_normal_true (ecma_completion_value_t value)
|
||||
extern bool ecma_is_completion_value_normal_false (ecma_completion_value_t value);
|
||||
extern bool ecma_is_empty_completion_value (ecma_completion_value_t value);
|
||||
|
||||
/* ecma-helpers-string.c */
|
||||
extern ecma_string_t* ecma_new_ecma_string (const ecma_char_t *string_p);
|
||||
extern void ecma_free_string (ecma_string_t *string_p);
|
||||
extern ssize_t ecma_string_to_zt_string (ecma_string_t *string_desc_p,
|
||||
ecma_char_t *buffer_p,
|
||||
size_t buffer_size);
|
||||
extern void ecma_ref_ecma_string (ecma_string_t *string_desc_p);
|
||||
extern int32_t ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p);
|
||||
extern bool ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p,
|
||||
const ecma_string_t *ecma_string_p);
|
||||
extern bool ecma_compare_ecma_string_to_ecma_string (const ecma_string_t *string1_p,
|
||||
const ecma_string_t *string2_p);
|
||||
|
||||
/* ecma-helpers.c */
|
||||
extern ecma_object_t* ecma_create_object (ecma_object_t *prototype_object_p,
|
||||
bool is_extensible,
|
||||
@@ -126,16 +139,6 @@ extern void ecma_free_property (ecma_property_t *prop_p);
|
||||
|
||||
extern void ecma_delete_property (ecma_object_t *obj_p, ecma_property_t *prop_p);
|
||||
|
||||
extern ecma_array_first_chunk_t* ecma_new_ecma_string (const ecma_char_t *string_p);
|
||||
extern ssize_t ecma_copy_ecma_string_chars_to_buffer (ecma_array_first_chunk_t *first_chunk_p,
|
||||
uint8_t *buffer_p,
|
||||
size_t buffer_size);
|
||||
extern ecma_array_first_chunk_t* ecma_duplicate_ecma_string (ecma_array_first_chunk_t *first_chunk_p);
|
||||
extern int32_t ecma_compare_zt_string_to_zt_string (const ecma_char_t *string1_p, const ecma_char_t *string2_p);
|
||||
extern bool ecma_compare_zt_string_to_ecma_string (const ecma_char_t *string_p,
|
||||
const ecma_array_first_chunk_t *ecma_string_p);
|
||||
extern bool ecma_compare_ecma_string_to_ecma_string (const ecma_array_first_chunk_t *string1_p,
|
||||
const ecma_array_first_chunk_t *string2_p);
|
||||
extern void ecma_free_array (ecma_array_first_chunk_t *first_chunk_p);
|
||||
|
||||
extern ecma_property_descriptor_t ecma_make_empty_property_descriptor (void);
|
||||
|
||||
@@ -80,10 +80,10 @@ ecma_op_abstract_equality_compare (ecma_value_t x, /**< first operand */
|
||||
}
|
||||
else if (is_x_string)
|
||||
{ // d.
|
||||
ecma_array_first_chunk_t* x_str = (ecma_array_first_chunk_t*)(ECMA_GET_POINTER(x.value));
|
||||
ecma_array_first_chunk_t* y_str = (ecma_array_first_chunk_t*)(ECMA_GET_POINTER(y.value));
|
||||
ecma_string_t* x_str_p = ECMA_GET_POINTER(x.value);
|
||||
ecma_string_t* y_str_p = ECMA_GET_POINTER(y.value);
|
||||
|
||||
return ecma_compare_ecma_string_to_ecma_string (x_str, y_str);
|
||||
return ecma_compare_ecma_string_to_ecma_string (x_str_p, y_str_p);
|
||||
}
|
||||
else if (is_x_boolean)
|
||||
{ // e.
|
||||
|
||||
@@ -134,8 +134,8 @@ ecma_op_same_value (ecma_value_t x, /**< ecma-value */
|
||||
|
||||
if (is_x_string)
|
||||
{
|
||||
ecma_array_first_chunk_t* x_str_p = (ecma_array_first_chunk_t*)(ECMA_GET_POINTER(x.value));
|
||||
ecma_array_first_chunk_t* y_str_p = (ecma_array_first_chunk_t*)(ECMA_GET_POINTER(y.value));
|
||||
ecma_string_t* x_str_p = ECMA_GET_POINTER(x.value);
|
||||
ecma_string_t* y_str_p = ECMA_GET_POINTER(y.value);
|
||||
|
||||
return ecma_compare_ecma_string_to_ecma_string (x_str_p, y_str_p);
|
||||
}
|
||||
@@ -234,9 +234,9 @@ ecma_op_to_boolean (ecma_value_t value) /**< ecma-value */
|
||||
}
|
||||
case ECMA_TYPE_STRING:
|
||||
{
|
||||
ecma_array_first_chunk_t *str_p = ECMA_GET_POINTER(value.value);
|
||||
ecma_string_t *str_p = ECMA_GET_POINTER(value.value);
|
||||
|
||||
return ecma_make_simple_completion_value ((str_p->header.unit_number == 0) ? ECMA_SIMPLE_VALUE_FALSE
|
||||
return ecma_make_simple_completion_value ((str_p->length == 0) ? ECMA_SIMPLE_VALUE_FALSE
|
||||
: ECMA_SIMPLE_VALUE_TRUE);
|
||||
|
||||
break;
|
||||
|
||||
Reference in New Issue
Block a user