migrate substitution keywords to SVN
[reactos.git] / reactos / lib / kjs / src / bc.c
1 /*
2 * Byte code handling routines.
3 * Copyright (c) 1998 New Generation Software (NGS) Oy
4 *
5 * Author: Markku Rossi <mtr@ngs.fi>
6 */
7
8 /*
9 * This library is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Library General Public
11 * License as published by the Free Software Foundation; either
12 * version 2 of the License, or (at your option) any later version.
13 *
14 * This library is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * Library General Public License for more details.
18 *
19 * You should have received a copy of the GNU Library General Public
20 * License along with this library; if not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
22 * MA 02111-1307, USA
23 */
24
25 /*
26 * $Source: /cygdrive/c/RCVS/CVS/ReactOS/reactos/lib/kjs/src/bc.c,v $
27 * $Id$
28 */
29
30 #include "jsint.h"
31
32 /*
33 * Global functions.
34 */
35
36 JSByteCode *
37 js_bc_read_file (FILE *fp)
38 {
39 unsigned char header[8];
40 JSUInt32 ui;
41 int i, got;
42 JSByteCode *bc = NULL;
43
44 if ((i = fgetc (fp)) == '#')
45 {
46 /* Skip the first line. */
47 while ((i = fgetc (fp)) != EOF && i != '\n')
48 ;
49 if (i == EOF)
50 goto format_error;
51 }
52 else
53 ungetc (i, fp);
54
55 got = fread (header, 4, 2, fp);
56 if (got != 2)
57 goto format_error;
58
59 JS_BC_READ_INT32 (header, ui);
60 if (ui != JS_BC_FILE_MAGIC)
61 goto format_error;
62
63 bc = js_calloc (NULL, 1, sizeof (*bc));
64 if (bc == NULL)
65 return NULL;
66
67
68 JS_BC_READ_INT32 (header + 4, ui);
69 bc->num_sects = (unsigned int) ui;
70
71 bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect));
72 if (bc->sects == NULL)
73 {
74 js_free (bc);
75 return NULL;
76 }
77
78 /* Read sections. */
79 for (i = 0; i < bc->num_sects; i++)
80 {
81 got = fread (header, 4, 2, fp);
82 if (got != 2)
83 goto format_error;
84
85 /* Get type. */
86 JS_BC_READ_INT32 (header, ui);
87 bc->sects[i].type = (int) ui;
88
89 /* Get section length. */
90 JS_BC_READ_INT32 (header + 4, ui);
91 bc->sects[i].length = (unsigned int) ui;
92 bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1
93 /* +1 to avoid zero allocations */);
94 if (bc->sects[i].data == NULL)
95 {
96 for (i--; i >= 0; i--)
97 js_free (bc->sects[i].data);
98
99 js_free (bc->sects);
100 js_free (bc);
101 return NULL;
102 }
103
104
105 /* Read section's data. */
106 got = fread (bc->sects[i].data, 1, bc->sects[i].length, fp);
107 if (got != bc->sects[i].length)
108 goto format_error;
109 }
110
111 return bc;
112
113 format_error:
114
115 if (bc)
116 js_bc_free (bc);
117
118 return NULL;
119 }
120
121
122 JSByteCode *
123 js_bc_read_data (unsigned char *data, unsigned int datalen)
124 {
125 JSUInt32 ui;
126 unsigned int pos = 0;
127 int i;
128 JSByteCode *bc = NULL;
129
130 if (data[pos] == '#')
131 {
132 /* Skip the first line. */
133 for (; pos < datalen && data[pos] != '\n'; pos++)
134 ;
135 if (pos >= datalen)
136 goto format_error;
137 }
138
139 if (datalen - pos < 8)
140 goto format_error;
141
142 JS_BC_READ_INT32 (data + pos, ui);
143 if (ui != JS_BC_FILE_MAGIC)
144 goto format_error;
145 pos += 4;
146
147 bc = js_calloc (NULL, 1, sizeof (*bc));
148 if (bc == NULL)
149 return NULL;
150
151 JS_BC_READ_INT32 (data + pos, ui);
152 bc->num_sects = (unsigned int) ui;
153 pos += 4;
154
155 bc->sects = js_calloc (NULL, bc->num_sects, sizeof (JSBCSect));
156 if (bc->sects == NULL)
157 {
158 js_free (bc);
159 return NULL;
160 }
161
162 /* Read sections. */
163 for (i = 0; i < bc->num_sects; i++)
164 {
165 if (datalen - pos < 8)
166 goto format_error;
167
168 /* Get type. */
169 JS_BC_READ_INT32 (data + pos, ui);
170 bc->sects[i].type = (int) ui;
171 pos += 4;
172
173 /* Get section length. */
174 JS_BC_READ_INT32 (data + pos, ui);
175 bc->sects[i].length = (unsigned int) ui;
176 pos += 4;
177
178 bc->sects[i].data = js_malloc (NULL, bc->sects[i].length + 1
179 /* +1 to avoid zero allocations */);
180 if (bc->sects[i].data == NULL)
181 {
182 for (i--; i >= 0; i--)
183 js_free (bc->sects[i].data);
184
185 js_free (bc->sects);
186 js_free (bc);
187 return NULL;
188 }
189
190 /* Read section's data. */
191 if (datalen - pos < bc->sects[i].length)
192 goto format_error;
193
194 memcpy (bc->sects[i].data, data + pos, bc->sects[i].length);
195 pos += bc->sects[i].length;
196 }
197
198 if (pos != datalen)
199 goto format_error;
200
201 return bc;
202
203
204 format_error:
205
206 if (bc)
207 js_bc_free (bc);
208
209 return NULL;
210 }
211
212
213 void
214 js_bc_free (JSByteCode *bc)
215 {
216 int i;
217
218 for (i = 0; i < bc->num_sects; i++)
219 if (bc->sects[i].data)
220 js_free (bc->sects[i].data);
221
222 js_free (bc->sects);
223 js_free (bc);
224 }