Allow closeable and nvm structures to be located by where they were allocated.
[SquirrelJME.git] / nanocoat / src / cleanup.c
blob39709a5e741a4f2a8512931aa68e6b4905283137
1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
3 // SquirrelJME
4 // Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
5 // ---------------------------------------------------------------------------
6 // SquirrelJME is under the Mozilla Public License Version 2.0.
7 // See license.mkd for licensing and copyright information.
8 // -------------------------------------------------------------------------*/
10 #include "sjme/cleanup.h"
11 #include "sjme/nvm/rom.h"
12 #include "sjme/nvm/stringPool.h"
13 #include "sjme/nvm/classy.h"
15 /** Simple free. */
16 #define SJME_CLEANUP_FREE(w) \
17 do { if ((w) != NULL) \
18 { \
19 if (sjme_error_is(error = sjme_alloc_free((w)))) \
20 return sjme_error_default(error); \
22 (w) = NULL; \
23 } } while(0)
25 /** Simple close. */
26 #define SJME_CLEANUP_CLOSE(x) \
27 do { if ((x) != NULL) \
28 { \
29 if (sjme_error_is(error = sjme_closeable_close( \
30 SJME_AS_CLOSEABLE((x))))) \
31 return sjme_error_default(error); \
33 (x) = NULL; \
34 } } while(0)
36 /** Cleanup of list. */
37 #define SJME_CLEANUP_LIST(y) \
38 do { if ((y) != NULL) \
39 { \
40 for (i = 0, n = (y)->length; i < n; i++) \
41 SJME_CLEANUP_CLOSE((y)->elements[i]); \
43 SJME_CLEANUP_FREE(y); \
44 } } while(0)
46 static sjme_errorCode sjme_class_classInfoClose(
47 sjme_attrInNotNull sjme_closeable closeable)
49 sjme_errorCode error;
50 sjme_class_info info;
51 sjme_jint i, n;
53 /* Recover. */
54 info = (sjme_class_info)closeable;
55 if (info == NULL)
56 return SJME_ERROR_NULL_ARGUMENTS;
58 SJME_CLEANUP_CLOSE(info->pool);
59 SJME_CLEANUP_CLOSE(info->name);
60 SJME_CLEANUP_CLOSE(info->superName);
61 SJME_CLEANUP_LIST(info->interfaceNames);
62 SJME_CLEANUP_LIST(info->fields);
63 SJME_CLEANUP_LIST(info->methods);
65 /* Success! */
66 return SJME_ERROR_NONE;
69 static sjme_errorCode sjme_class_constantPoolClose(
70 sjme_attrInNotNull sjme_closeable closeable)
72 sjme_errorCode error;
73 sjme_class_poolInfo info;
74 sjme_class_poolEntry* entry;
75 sjme_jint i, n;
77 /* Recover. */
78 info = (sjme_class_poolInfo)closeable;
79 if (info == NULL)
80 return SJME_ERROR_NULL_ARGUMENTS;
82 /* Cleanup any pool entries. */
83 if (info->pool != NULL)
84 for (i = 0, n = info->pool->length; i < n; i++)
86 entry = &info->pool->elements[i];
87 switch (entry->type)
89 case SJME_CLASS_POOL_TYPE_UTF:
90 SJME_CLEANUP_CLOSE(entry->utf.utf);
91 break;
93 case SJME_CLASS_POOL_TYPE_CLASS:
94 SJME_CLEANUP_CLOSE(entry->classRef.descriptor);
95 break;
97 case SJME_CLASS_POOL_TYPE_STRING:
98 SJME_CLEANUP_CLOSE(entry->constString.value);
99 break;
101 case SJME_CLASS_POOL_TYPE_NAME_AND_TYPE:
102 SJME_CLEANUP_CLOSE(entry->nameAndType.descriptor);
103 SJME_CLEANUP_CLOSE(entry->nameAndType.name);
104 break;
108 /* Free list. */
109 SJME_CLEANUP_FREE(info->pool);
111 /* Success! */
112 return SJME_ERROR_NONE;
115 static sjme_errorCode sjme_class_fieldInfoClose(
116 sjme_attrInNotNull sjme_closeable closeable)
118 sjme_errorCode error;
119 sjme_class_fieldInfo info;
120 sjme_jint i, n;
122 /* Recover. */
123 info = (sjme_class_fieldInfo)closeable;
124 if (info == NULL)
125 return SJME_ERROR_NULL_ARGUMENTS;
127 SJME_CLEANUP_CLOSE(info->inClass);
128 SJME_CLEANUP_CLOSE(info->name);
129 SJME_CLEANUP_CLOSE(info->type);
131 /* Success! */
132 return SJME_ERROR_NONE;
135 static sjme_errorCode sjme_class_methodInfoClose(
136 sjme_attrInNotNull sjme_closeable closeable)
138 sjme_errorCode error;
139 sjme_class_methodInfo info;
140 sjme_jint i, n;
142 /* Recover. */
143 info = (sjme_class_methodInfo)closeable;
144 if (info == NULL)
145 return SJME_ERROR_NULL_ARGUMENTS;
147 SJME_CLEANUP_CLOSE(info->inClass);
148 SJME_CLEANUP_CLOSE(info->name);
149 SJME_CLEANUP_CLOSE(info->type);
150 SJME_CLEANUP_CLOSE(info->code);
152 /* Success! */
153 return SJME_ERROR_NONE;
156 static sjme_errorCode sjme_desc_identifierClose(
157 sjme_attrInNotNull sjme_closeable closeable)
159 sjme_errorCode error;
160 sjme_desc_identifier info;
162 /* Recover. */
163 info = (sjme_desc_identifier)closeable;
164 if (info == NULL)
165 return SJME_ERROR_NULL_ARGUMENTS;
167 SJME_CLEANUP_CLOSE(info->whole);
169 /* Success! */
170 return SJME_ERROR_NONE;
173 static sjme_errorCode sjme_rom_libraryClose(
174 sjme_attrInNotNull sjme_closeable closeable)
176 sjme_errorCode error;
177 sjme_rom_library inLibrary;
179 /* Recover library. */
180 inLibrary = (sjme_rom_library)closeable;
181 if (inLibrary == NULL)
182 return SJME_ERROR_NULL_ARGUMENTS;
184 /* Delete the prefix if there is one. */
185 if (inLibrary->prefix != NULL)
187 /* Free it. */
188 if (sjme_error_is(error = sjme_alloc_free(
189 (sjme_pointer)inLibrary->prefix)))
190 return sjme_error_default(error);
192 /* Clear. */
193 inLibrary->prefix = NULL;
196 /* Delete name if there is one. */
197 if (inLibrary->name != NULL)
199 /* Free it. */
200 if (sjme_error_is(error = sjme_alloc_free(
201 (sjme_pointer)inLibrary->name)))
202 return sjme_error_default(error);
204 /* Clear. */
205 inLibrary->name = NULL;
208 /* Forward close handler. */
209 if (inLibrary->functions->close != NULL)
210 return inLibrary->functions->close(inLibrary);
212 /* Success! */
213 return SJME_ERROR_NONE;
216 static sjme_errorCode sjme_rom_suiteClose(
217 sjme_attrInNotNull sjme_closeable closeable)
219 if (closeable == NULL)
220 return SJME_ERROR_NULL_ARGUMENTS;
222 sjme_todo("Impl?");
223 return sjme_error_notImplemented(0);
226 static sjme_errorCode sjme_stringPool_close(
227 sjme_attrInNullable sjme_closeable closeable)
229 sjme_errorCode error;
230 sjme_stringPool stringPool;
231 sjme_jint i, n;
232 sjme_list_sjme_stringPool_string* strings;
233 sjme_stringPool_string target;
235 /* Recover pool. */
236 stringPool = (sjme_stringPool)closeable;
237 if (stringPool == NULL)
238 return SJME_ERROR_NULL_ARGUMENTS;
240 /* Loaded string cleanup. */
241 strings = stringPool->strings;
242 if (strings != NULL)
244 /* Close every contained string. */
245 for (i = 0, n = strings->length; i < n; i++)
247 /* Skip blanks. */
248 target = strings->elements[i];
249 if (target == NULL)
250 continue;
252 /* Close individual string. */
253 if (sjme_error_is(error = sjme_closeable_close(
254 SJME_AS_CLOSEABLE(target))))
255 return sjme_error_default(error);
257 /* Clear it. */
258 strings->elements[i] = NULL;
261 /* Destroy list. */
262 if (sjme_error_is(error = sjme_alloc_free(strings)))
263 return sjme_error_default(error);
264 strings = NULL;
267 /* Wipe. */
268 stringPool->inPool = NULL;
270 /* Success! */
271 return SJME_ERROR_NONE;
274 static sjme_errorCode sjme_stringPool_stringClose(
275 sjme_attrInNotNull sjme_closeable closeable)
277 sjme_errorCode error;
278 sjme_stringPool_string info;
280 /* Recover. */
281 info = (sjme_stringPool_string)closeable;
282 if (info == NULL)
283 return SJME_ERROR_NULL_ARGUMENTS;
285 /* Success! */
286 return SJME_ERROR_NONE;
289 /* ------------------------------------------------------------------------ */
291 sjme_errorCode sjme_nvm_allocR(
292 sjme_attrInNotNull sjme_alloc_pool* inPool,
293 sjme_attrInPositiveNonZero sjme_jint allocSize,
294 sjme_attrInValue sjme_nvm_structType inType,
295 sjme_attrOutNotNull sjme_nvm_common* outCommon
296 SJME_DEBUG_ONLY_COMMA SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL)
298 sjme_errorCode error;
299 sjme_closeable_closeHandlerFunc handler;
300 sjme_nvm_common result;
302 if (inPool == NULL || outCommon == NULL)
303 return SJME_ERROR_NULL_ARGUMENTS;
305 if (inType <= SJME_NVM_STRUCT_UNKNOWN ||
306 inType >= SJME_NVM_NUM_STRUCT)
307 return SJME_ERROR_INVALID_ARGUMENT;
309 /* Which handler is used? */
310 handler = NULL;
311 switch (inType)
313 case SJME_NVM_STRUCT_CLASS_INFO:
314 handler = sjme_class_classInfoClose;
315 break;
317 case SJME_NVM_STRUCT_FIELD_INFO:
318 handler = sjme_class_fieldInfoClose;
319 break;
321 case SJME_NVM_STRUCT_IDENTIFIER:
322 handler = sjme_desc_identifierClose;
323 break;
325 case SJME_NVM_STRUCT_METHOD_INFO:
326 handler = sjme_class_methodInfoClose;
327 break;
329 case SJME_NVM_STRUCT_POOL:
330 handler = sjme_class_constantPoolClose;
331 break;
333 case SJME_NVM_STRUCT_ROM_LIBRARY:
334 handler = sjme_rom_libraryClose;
335 break;
337 case SJME_NVM_STRUCT_ROM_SUITE:
338 handler = sjme_rom_suiteClose;
339 break;
341 case SJME_NVM_STRUCT_STRING_POOL:
342 handler = sjme_stringPool_close;
343 break;
345 case SJME_NVM_STRUCT_STRING_POOL_STRING:
346 handler = sjme_stringPool_stringClose;
347 break;
349 default:
350 sjme_todo("Impl? %d", inType);
351 return sjme_error_notImplemented(0);
354 /* Allocate result. */
355 result = NULL;
356 #if defined(SJME_CONFIG_DEBUG)
357 if (sjme_error_is(error = sjme_closeable_allocR(inPool,
358 allocSize, handler, SJME_JNI_TRUE,
359 SJME_AS_CLOSEABLEP(&result), file, line, func)) ||
360 result == NULL)
361 #else
362 if (sjme_error_is(error = sjme_closeable_alloc(inPool,
363 allocSize, handler, SJME_JNI_TRUE,
364 SJME_AS_CLOSEABLEP(&result))) || result == NULL)
365 #endif
366 return sjme_error_default(error);
368 /* Set fields. */
369 result->type = inType;
371 /* Success! */
372 *outCommon = result;
373 return SJME_ERROR_NONE;