jscript: Added parser memory managment.
[wine] / dlls / jscript / jsutils.c
1 /*
2  * Copyright 2008 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include "jscript.h"
20
21 #include "wine/debug.h"
22
23 WINE_DEFAULT_DEBUG_CHANNEL(jscript);
24
25 #define MIN_BLOCK_SIZE  128
26
27 static inline DWORD block_size(DWORD block)
28 {
29     return MIN_BLOCK_SIZE << block;
30 }
31
32 void jsheap_init(jsheap_t *heap)
33 {
34     memset(heap, 0, sizeof(*heap));
35     list_init(&heap->custom_blocks);
36 }
37
38 void *jsheap_alloc(jsheap_t *heap, DWORD size)
39 {
40     struct list *list;
41     void *tmp;
42
43     if(!heap->block_cnt) {
44         if(!heap->blocks) {
45             heap->blocks = heap_alloc(sizeof(void*));
46             if(!heap->blocks)
47                 return NULL;
48         }
49
50         tmp = heap_alloc(block_size(0));
51         if(!tmp)
52             return NULL;
53
54         heap->blocks[0] = tmp;
55         heap->block_cnt = 1;
56     }
57
58     if(heap->offset + size < block_size(heap->last_block)) {
59         tmp = ((BYTE*)heap->blocks[heap->last_block])+heap->offset;
60         heap->offset += size;
61         return tmp;
62     }
63
64     if(size < block_size(heap->last_block+1)) {
65         if(heap->last_block+1 == heap->block_cnt) {
66             tmp = heap_realloc(heap->blocks, (heap->block_cnt+1)*sizeof(void*));
67             if(!tmp)
68                 return NULL;
69             heap->blocks = tmp;
70         }
71
72         tmp = heap_alloc(block_size(heap->block_cnt+1));
73         if(!tmp)
74             return NULL;
75
76         heap->blocks[heap->block_cnt++] = tmp;
77
78         heap->last_block++;
79         heap->offset = size;
80         return heap->blocks[heap->last_block];
81     }
82
83     list = heap_alloc(size + sizeof(struct list));
84     if(!list)
85         return NULL;
86
87     list_add_head(&heap->custom_blocks, list);
88     return list+1;
89 }
90
91 void jsheap_clear(jsheap_t *heap)
92 {
93     struct list *tmp;
94
95     while((tmp = list_next(&heap->custom_blocks, &heap->custom_blocks))) {
96         list_remove(tmp);
97         heap_free(tmp);
98     }
99 }
100
101 void jsheap_free(jsheap_t *heap)
102 {
103     DWORD i;
104
105     jsheap_clear(heap);
106
107     for(i=0; i < heap->block_cnt; i++)
108         heap_free(heap->blocks[i]);
109     heap_free(heap->blocks);
110
111     jsheap_init(heap);
112 }