1425bb815Sopenharmony_ci/* Copyright JS Foundation and other contributors, http://js.foundation 2425bb815Sopenharmony_ci * 3425bb815Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4425bb815Sopenharmony_ci * you may not use this file except in compliance with the License. 5425bb815Sopenharmony_ci * You may obtain a copy of the License at 6425bb815Sopenharmony_ci * 7425bb815Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8425bb815Sopenharmony_ci * 9425bb815Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10425bb815Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS 11425bb815Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12425bb815Sopenharmony_ci * See the License for the specific language governing permissions and 13425bb815Sopenharmony_ci * limitations under the License. 14425bb815Sopenharmony_ci */ 15425bb815Sopenharmony_ci 16425bb815Sopenharmony_ci#include <stdlib.h> 17425bb815Sopenharmony_ci#include "handle-scope-internal.h" 18425bb815Sopenharmony_ci 19425bb815Sopenharmony_cistatic jerryx_handle_scope_t jerryx_handle_scope_root = 20425bb815Sopenharmony_ci{ 21425bb815Sopenharmony_ci .prelist_handle_count = 0, 22425bb815Sopenharmony_ci .handle_ptr = NULL, 23425bb815Sopenharmony_ci}; 24425bb815Sopenharmony_cistatic jerryx_handle_scope_t *jerryx_handle_scope_current = &jerryx_handle_scope_root; 25425bb815Sopenharmony_cistatic jerryx_handle_scope_pool_t jerryx_handle_scope_pool = 26425bb815Sopenharmony_ci{ 27425bb815Sopenharmony_ci .count = 0, 28425bb815Sopenharmony_ci .start = NULL, 29425bb815Sopenharmony_ci}; 30425bb815Sopenharmony_ci 31425bb815Sopenharmony_ci#define JERRYX_HANDLE_SCOPE_POOL_PRELIST_LAST \ 32425bb815Sopenharmony_ci jerryx_handle_scope_pool.prelist + JERRYX_SCOPE_PRELIST_SIZE - 1 33425bb815Sopenharmony_ci 34425bb815Sopenharmony_ci#define JERRYX_HANDLE_SCOPE_PRELIST_IDX(scope) (scope - jerryx_handle_scope_pool.prelist) 35425bb815Sopenharmony_ci 36425bb815Sopenharmony_ci/** 37425bb815Sopenharmony_ci * Get current handle scope top of stack. 38425bb815Sopenharmony_ci */ 39425bb815Sopenharmony_cijerryx_handle_scope_t * 40425bb815Sopenharmony_cijerryx_handle_scope_get_current (void) 41425bb815Sopenharmony_ci{ 42425bb815Sopenharmony_ci return jerryx_handle_scope_current; 43425bb815Sopenharmony_ci} /* jerryx_handle_scope_get_current */ 44425bb815Sopenharmony_ci 45425bb815Sopenharmony_ci/** 46425bb815Sopenharmony_ci * Get root handle scope. 47425bb815Sopenharmony_ci */ 48425bb815Sopenharmony_cijerryx_handle_scope_t * 49425bb815Sopenharmony_cijerryx_handle_scope_get_root (void) 50425bb815Sopenharmony_ci{ 51425bb815Sopenharmony_ci return &jerryx_handle_scope_root; 52425bb815Sopenharmony_ci} /* jerryx_handle_scope_get_root */ 53425bb815Sopenharmony_ci 54425bb815Sopenharmony_ci/** 55425bb815Sopenharmony_ci * Determines if given handle scope is located in pre-allocated list. 56425bb815Sopenharmony_ci * 57425bb815Sopenharmony_ci * @param scope - the one to be determined. 58425bb815Sopenharmony_ci */ 59425bb815Sopenharmony_cistatic bool 60425bb815Sopenharmony_cijerryx_handle_scope_is_in_prelist (jerryx_handle_scope_t *scope) 61425bb815Sopenharmony_ci{ 62425bb815Sopenharmony_ci return (jerryx_handle_scope_pool.prelist <= scope) 63425bb815Sopenharmony_ci && (scope <= (jerryx_handle_scope_pool.prelist + JERRYX_SCOPE_PRELIST_SIZE - 1)); 64425bb815Sopenharmony_ci} /** jerryx_handle_scope_is_in_prelist */ 65425bb815Sopenharmony_ci 66425bb815Sopenharmony_ci/** 67425bb815Sopenharmony_ci * Get the parent of given handle scope. 68425bb815Sopenharmony_ci * If given handle scope is in prelist, the parent must be in prelist too; 69425bb815Sopenharmony_ci * if given is the first item of heap chain list, the parent must be the last one of prelist; 70425bb815Sopenharmony_ci * the parent must be in chain list otherwise. 71425bb815Sopenharmony_ci * 72425bb815Sopenharmony_ci * @param scope - the one to be permformed on. 73425bb815Sopenharmony_ci * @returns - the parent of the given scope. 74425bb815Sopenharmony_ci */ 75425bb815Sopenharmony_cijerryx_handle_scope_t * 76425bb815Sopenharmony_cijerryx_handle_scope_get_parent (jerryx_handle_scope_t *scope) 77425bb815Sopenharmony_ci{ 78425bb815Sopenharmony_ci if (scope == &jerryx_handle_scope_root) 79425bb815Sopenharmony_ci { 80425bb815Sopenharmony_ci return NULL; 81425bb815Sopenharmony_ci } 82425bb815Sopenharmony_ci if (!jerryx_handle_scope_is_in_prelist (scope)) 83425bb815Sopenharmony_ci { 84425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *dy_scope = (jerryx_handle_scope_dynamic_t *) scope; 85425bb815Sopenharmony_ci if (dy_scope == jerryx_handle_scope_pool.start) 86425bb815Sopenharmony_ci { 87425bb815Sopenharmony_ci return JERRYX_HANDLE_SCOPE_POOL_PRELIST_LAST; 88425bb815Sopenharmony_ci } 89425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *parent = dy_scope->parent; 90425bb815Sopenharmony_ci return (jerryx_handle_scope_t *) parent; 91425bb815Sopenharmony_ci } 92425bb815Sopenharmony_ci if (scope == jerryx_handle_scope_pool.prelist) 93425bb815Sopenharmony_ci { 94425bb815Sopenharmony_ci return &jerryx_handle_scope_root; 95425bb815Sopenharmony_ci } 96425bb815Sopenharmony_ci return jerryx_handle_scope_pool.prelist + JERRYX_HANDLE_SCOPE_PRELIST_IDX (scope) - 1; 97425bb815Sopenharmony_ci} /** jerryx_handle_scope_get_parent */ 98425bb815Sopenharmony_ci 99425bb815Sopenharmony_ci/** 100425bb815Sopenharmony_ci * Get the child of given handle scope. 101425bb815Sopenharmony_ci * If the given handle scope is in heap chain list, its child must be in heap chain list too; 102425bb815Sopenharmony_ci * if the given handle scope is the last one of prelist, its child must be the first item of chain list; 103425bb815Sopenharmony_ci * the children are in prelist otherwise. 104425bb815Sopenharmony_ci * 105425bb815Sopenharmony_ci * @param scope - the one to be permformed on. 106425bb815Sopenharmony_ci * @returns the child of the given scope. 107425bb815Sopenharmony_ci */ 108425bb815Sopenharmony_cijerryx_handle_scope_t * 109425bb815Sopenharmony_cijerryx_handle_scope_get_child (jerryx_handle_scope_t *scope) 110425bb815Sopenharmony_ci{ 111425bb815Sopenharmony_ci if (scope == &jerryx_handle_scope_root) 112425bb815Sopenharmony_ci { 113425bb815Sopenharmony_ci if (jerryx_handle_scope_pool.count > 0) 114425bb815Sopenharmony_ci { 115425bb815Sopenharmony_ci return jerryx_handle_scope_pool.prelist; 116425bb815Sopenharmony_ci } 117425bb815Sopenharmony_ci return NULL; 118425bb815Sopenharmony_ci } 119425bb815Sopenharmony_ci if (!jerryx_handle_scope_is_in_prelist (scope)) 120425bb815Sopenharmony_ci { 121425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *child = ((jerryx_handle_scope_dynamic_t *) scope)->child; 122425bb815Sopenharmony_ci return (jerryx_handle_scope_t *) child; 123425bb815Sopenharmony_ci } 124425bb815Sopenharmony_ci if (scope == JERRYX_HANDLE_SCOPE_POOL_PRELIST_LAST) 125425bb815Sopenharmony_ci { 126425bb815Sopenharmony_ci return (jerryx_handle_scope_t *) jerryx_handle_scope_pool.start; 127425bb815Sopenharmony_ci } 128425bb815Sopenharmony_ci long idx = (long)(JERRYX_HANDLE_SCOPE_PRELIST_IDX (scope)); 129425bb815Sopenharmony_ci if (idx < 0) 130425bb815Sopenharmony_ci { 131425bb815Sopenharmony_ci return NULL; 132425bb815Sopenharmony_ci } 133425bb815Sopenharmony_ci if ((unsigned long) idx >= jerryx_handle_scope_pool.count - 1) 134425bb815Sopenharmony_ci { 135425bb815Sopenharmony_ci return NULL; 136425bb815Sopenharmony_ci } 137425bb815Sopenharmony_ci return jerryx_handle_scope_pool.prelist + idx + 1; 138425bb815Sopenharmony_ci} /** jerryx_handle_scope_get_child */ 139425bb815Sopenharmony_ci 140425bb815Sopenharmony_ci/** 141425bb815Sopenharmony_ci * Claims a handle scope either from prelist or allocating a new memory block, 142425bb815Sopenharmony_ci * and increment pool's scope count by 1, and set current scope to the newly claimed one. 143425bb815Sopenharmony_ci * If there are still available spaces in prelist, claims a block in prelist; 144425bb815Sopenharmony_ci * otherwise allocates a new memory block from heap and sets its fields to default values, 145425bb815Sopenharmony_ci * and link it to previously dynamically allocated scope, or link it to pool's start pointer. 146425bb815Sopenharmony_ci * 147425bb815Sopenharmony_ci * @returns the newly claimed handle scope pointer. 148425bb815Sopenharmony_ci */ 149425bb815Sopenharmony_cijerryx_handle_scope_t * 150425bb815Sopenharmony_cijerryx_handle_scope_alloc (void) 151425bb815Sopenharmony_ci{ 152425bb815Sopenharmony_ci jerryx_handle_scope_t *scope; 153425bb815Sopenharmony_ci if (jerryx_handle_scope_pool.count < JERRYX_SCOPE_PRELIST_SIZE) 154425bb815Sopenharmony_ci { 155425bb815Sopenharmony_ci scope = jerryx_handle_scope_pool.prelist + jerryx_handle_scope_pool.count; 156425bb815Sopenharmony_ci } 157425bb815Sopenharmony_ci else 158425bb815Sopenharmony_ci { 159425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *dy_scope = malloc (sizeof (jerryx_handle_scope_dynamic_t)); 160425bb815Sopenharmony_ci JERRYX_HANDLE_SCOPE_ASSERT (dy_scope != NULL); 161425bb815Sopenharmony_ci dy_scope->child = NULL; 162425bb815Sopenharmony_ci 163425bb815Sopenharmony_ci if (jerryx_handle_scope_pool.count != JERRYX_SCOPE_PRELIST_SIZE) 164425bb815Sopenharmony_ci { 165425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *dy_current = (jerryx_handle_scope_dynamic_t *) jerryx_handle_scope_current; 166425bb815Sopenharmony_ci dy_scope->parent = dy_current; 167425bb815Sopenharmony_ci dy_current->child = dy_scope; 168425bb815Sopenharmony_ci } 169425bb815Sopenharmony_ci else 170425bb815Sopenharmony_ci { 171425bb815Sopenharmony_ci jerryx_handle_scope_pool.start = dy_scope; 172425bb815Sopenharmony_ci dy_scope->parent = NULL; 173425bb815Sopenharmony_ci } 174425bb815Sopenharmony_ci 175425bb815Sopenharmony_ci scope = (jerryx_handle_scope_t *) dy_scope; 176425bb815Sopenharmony_ci } 177425bb815Sopenharmony_ci 178425bb815Sopenharmony_ci scope->prelist_handle_count = 0; 179425bb815Sopenharmony_ci scope->escaped = false; 180425bb815Sopenharmony_ci scope->handle_ptr = NULL; 181425bb815Sopenharmony_ci 182425bb815Sopenharmony_ci jerryx_handle_scope_current = scope; 183425bb815Sopenharmony_ci ++jerryx_handle_scope_pool.count; 184425bb815Sopenharmony_ci return (jerryx_handle_scope_t *) scope; 185425bb815Sopenharmony_ci} /** jerryx_handle_scope_alloc */ 186425bb815Sopenharmony_ci 187425bb815Sopenharmony_ci/** 188425bb815Sopenharmony_ci * Deannounce a previously claimed handle scope, return it to pool 189425bb815Sopenharmony_ci * or free the allocated memory block. 190425bb815Sopenharmony_ci * 191425bb815Sopenharmony_ci * @param scope - the one to be freed. 192425bb815Sopenharmony_ci */ 193425bb815Sopenharmony_civoid 194425bb815Sopenharmony_cijerryx_handle_scope_free (jerryx_handle_scope_t *scope) 195425bb815Sopenharmony_ci{ 196425bb815Sopenharmony_ci if (scope == &jerryx_handle_scope_root) 197425bb815Sopenharmony_ci { 198425bb815Sopenharmony_ci return; 199425bb815Sopenharmony_ci } 200425bb815Sopenharmony_ci 201425bb815Sopenharmony_ci --jerryx_handle_scope_pool.count; 202425bb815Sopenharmony_ci if (scope == jerryx_handle_scope_current) 203425bb815Sopenharmony_ci { 204425bb815Sopenharmony_ci jerryx_handle_scope_current = jerryx_handle_scope_get_parent (scope); 205425bb815Sopenharmony_ci } 206425bb815Sopenharmony_ci 207425bb815Sopenharmony_ci if (!jerryx_handle_scope_is_in_prelist (scope)) 208425bb815Sopenharmony_ci { 209425bb815Sopenharmony_ci jerryx_handle_scope_dynamic_t *dy_scope = (jerryx_handle_scope_dynamic_t *) scope; 210425bb815Sopenharmony_ci if (dy_scope == jerryx_handle_scope_pool.start) 211425bb815Sopenharmony_ci { 212425bb815Sopenharmony_ci jerryx_handle_scope_pool.start = dy_scope->child; 213425bb815Sopenharmony_ci } 214425bb815Sopenharmony_ci else if (dy_scope->parent != NULL) 215425bb815Sopenharmony_ci { 216425bb815Sopenharmony_ci dy_scope->parent->child = dy_scope->child; 217425bb815Sopenharmony_ci } 218425bb815Sopenharmony_ci free (dy_scope); 219425bb815Sopenharmony_ci return; 220425bb815Sopenharmony_ci } 221425bb815Sopenharmony_ci /** 222425bb815Sopenharmony_ci * Nothing to do with scopes in prelist 223425bb815Sopenharmony_ci */ 224425bb815Sopenharmony_ci} /** jerryx_handle_scope_free */ 225