1/* Copyright JS Foundation and other contributors, http://js.foundation 2 * 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16#include "ecma-alloc.h" 17#include "ecma-gc.h" 18#include "ecma-globals.h" 19#include "ecma-helpers.h" 20#include "jrt.h" 21 22/** \addtogroup ecma ECMA 23 * @{ 24 * 25 * \addtogroup ecmahelpers Helpers for operations with ECMA data types 26 * @{ 27 */ 28 29/** 30 * Allocate a collection of ecma values. 31 * 32 * @return pointer to the collection 33 */ 34ecma_collection_t * 35ecma_new_collection (void) 36{ 37 ecma_collection_t *collection_p; 38 collection_p = (ecma_collection_t *) jmem_heap_alloc_block (sizeof (ecma_collection_t)); 39 40 collection_p->item_count = 0; 41 collection_p->capacity = ECMA_COLLECTION_INITIAL_CAPACITY; 42 const uint32_t size = ECMA_COLLECTION_ALLOCATED_SIZE (ECMA_COLLECTION_INITIAL_CAPACITY); 43 collection_p->buffer_p = (ecma_value_t *) jmem_heap_alloc_block (size); 44 45 return collection_p; 46} /* ecma_new_collection */ 47 48/** 49 * Deallocate a collection of ecma values without freeing it's values 50 */ 51inline void JERRY_ATTR_ALWAYS_INLINE 52ecma_collection_destroy (ecma_collection_t *collection_p) /**< value collection */ 53{ 54 JERRY_ASSERT (collection_p != NULL); 55 56 jmem_heap_free_block (collection_p->buffer_p, ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity)); 57 jmem_heap_free_block (collection_p, sizeof (ecma_collection_t)); 58} /* ecma_collection_destroy */ 59 60/** 61 * Free the object collection elements and deallocate the collection 62 */ 63void 64ecma_collection_free_objects (ecma_collection_t *collection_p) /**< value collection */ 65{ 66 JERRY_ASSERT (collection_p != NULL); 67 68 ecma_value_t *buffer_p = collection_p->buffer_p; 69 70 for (uint32_t i = 0; i < collection_p->item_count; i++) 71 { 72 if (ecma_is_value_object (buffer_p[i])) 73 { 74 ecma_deref_object (ecma_get_object_from_value (buffer_p[i])); 75 } 76 } 77 78 ecma_collection_destroy (collection_p); 79} /* ecma_collection_free_objects */ 80 81/** 82 * Free the non-object collection elements and deallocate the collection 83 */ 84void 85ecma_collection_free_if_not_object (ecma_collection_t *collection_p) /**< value collection */ 86{ 87 JERRY_ASSERT (collection_p != NULL); 88 89 ecma_value_t *buffer_p = collection_p->buffer_p; 90 91 for (uint32_t i = 0; i < collection_p->item_count; i++) 92 { 93 ecma_free_value_if_not_object (buffer_p[i]); 94 } 95 96 ecma_collection_destroy (collection_p); 97} /* ecma_collection_free_if_not_object */ 98 99/** 100 * Free the collection elements and deallocate the collection 101 */ 102void 103ecma_collection_free (ecma_collection_t *collection_p) /**< value collection */ 104{ 105 JERRY_ASSERT (collection_p != NULL); 106 107 ecma_value_t *buffer_p = collection_p->buffer_p; 108 109 for (uint32_t i = 0; i < collection_p->item_count; i++) 110 { 111 ecma_free_value (buffer_p[i]); 112 } 113 114 ecma_collection_destroy (collection_p); 115} /* ecma_collection_free */ 116 117/** 118 * Append new value to ecma values collection 119 * 120 * Note: The reference count of the values are not increased 121 */ 122void 123ecma_collection_push_back (ecma_collection_t *collection_p, /**< value collection */ 124 ecma_value_t value) /**< ecma value to append */ 125{ 126 JERRY_ASSERT (collection_p != NULL); 127 128 ecma_value_t *buffer_p = collection_p->buffer_p; 129 130 if (JERRY_LIKELY (collection_p->item_count < collection_p->capacity)) 131 { 132 buffer_p[collection_p->item_count++] = value; 133 return; 134 } 135 136 const uint32_t new_capacity = collection_p->capacity + ECMA_COLLECTION_GROW_FACTOR; 137 const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity); 138 const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity); 139 140 buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size); 141 buffer_p[collection_p->item_count++] = value; 142 collection_p->capacity = new_capacity; 143 144 collection_p->buffer_p = buffer_p; 145} /* ecma_collection_push_back */ 146 147/** 148 * Reserve space for the given amount of ecma_values in the collection 149 */ 150void 151ecma_collection_reserve (ecma_collection_t *collection_p, /**< value collection */ 152 uint32_t count) /**< number of ecma values to reserve */ 153{ 154 JERRY_ASSERT (collection_p != NULL); 155 JERRY_ASSERT (UINT32_MAX - count > collection_p->capacity); 156 157 const uint32_t new_capacity = collection_p->capacity + count; 158 const uint32_t old_size = ECMA_COLLECTION_ALLOCATED_SIZE (collection_p->capacity); 159 const uint32_t new_size = ECMA_COLLECTION_ALLOCATED_SIZE (new_capacity); 160 161 ecma_value_t *buffer_p = collection_p->buffer_p; 162 buffer_p = jmem_heap_realloc_block (buffer_p, old_size, new_size); 163 164 collection_p->capacity = new_capacity; 165 collection_p->buffer_p = buffer_p; 166} /* ecma_collection_reserve */ 167 168/** 169 * Append a list of values to the end of the collection 170 */ 171void 172ecma_collection_append (ecma_collection_t *collection_p, /**< value collection */ 173 const ecma_value_t *buffer_p, /**< values to append */ 174 uint32_t count) /**< number of ecma values to append */ 175{ 176 JERRY_ASSERT (collection_p != NULL); 177 JERRY_ASSERT (collection_p->capacity >= collection_p->item_count); 178 179 uint32_t free_count = collection_p->capacity - collection_p->item_count; 180 181 if (free_count < count) 182 { 183 ecma_collection_reserve (collection_p, count - free_count); 184 } 185 186 memcpy (collection_p->buffer_p + collection_p->item_count, buffer_p, count * sizeof (ecma_value_t)); 187 collection_p->item_count += count; 188} /* ecma_collection_append */ 189 190/** 191 * @} 192 * @} 193 */ 194