1 /* -*- Mode: C; indent-tabs-mode: t; tab-width: 4 -*-
2 // ---------------------------------------------------------------------------
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"
16 #define SJME_CLEANUP_FREE(w) \
17 do { if ((w) != NULL) \
19 if (sjme_error_is(error = sjme_alloc_free((w)))) \
20 return sjme_error_default(error); \
26 #define SJME_CLEANUP_CLOSE(x) \
27 do { if ((x) != NULL) \
29 if (sjme_error_is(error = sjme_closeable_close( \
30 SJME_AS_CLOSEABLE((x))))) \
31 return sjme_error_default(error); \
36 /** Cleanup of list. */
37 #define SJME_CLEANUP_LIST(y) \
38 do { if ((y) != NULL) \
40 for (i = 0, n = (y)->length; i < n; i++) \
41 SJME_CLEANUP_CLOSE((y)->elements[i]); \
43 SJME_CLEANUP_FREE(y); \
46 static sjme_errorCode
sjme_class_classInfoClose(
47 sjme_attrInNotNull sjme_closeable closeable
)
54 info
= (sjme_class_info
)closeable
;
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
);
66 return SJME_ERROR_NONE
;
70 static sjme_errorCode
sjme_class_codeInfoClose(
71 sjme_attrInNotNull sjme_closeable closeable
)
74 sjme_class_codeInfo info
;
78 info
= (sjme_class_codeInfo
)closeable
;
80 return SJME_ERROR_NULL_ARGUMENTS
;
82 SJME_CLEANUP_CLOSE(info
->inMethod
);
83 SJME_CLEANUP_FREE(info
->exceptions
);
86 return SJME_ERROR_NONE
;
89 static sjme_errorCode
sjme_class_constantPoolClose(
90 sjme_attrInNotNull sjme_closeable closeable
)
93 sjme_class_poolInfo info
;
94 sjme_class_poolEntry
* entry
;
98 info
= (sjme_class_poolInfo
)closeable
;
100 return SJME_ERROR_NULL_ARGUMENTS
;
102 /* Cleanup any pool entries. */
103 if (info
->pool
!= NULL
)
104 for (i
= 0, n
= info
->pool
->length
; i
< n
; i
++)
106 entry
= &info
->pool
->elements
[i
];
109 case SJME_CLASS_POOL_TYPE_CLASS
:
110 SJME_CLEANUP_CLOSE(entry
->classRef
.descriptor
);
113 case SJME_CLASS_POOL_TYPE_STRING
:
114 SJME_CLEANUP_CLOSE(entry
->constString
.value
);
117 case SJME_CLASS_POOL_TYPE_NAME_AND_TYPE
:
118 SJME_CLEANUP_CLOSE(entry
->nameAndType
.descriptor
);
119 SJME_CLEANUP_CLOSE(entry
->nameAndType
.name
);
122 case SJME_CLASS_POOL_TYPE_UTF
:
123 SJME_CLEANUP_CLOSE(entry
->utf
.utf
);
129 SJME_CLEANUP_FREE(info
->pool
);
132 return SJME_ERROR_NONE
;
135 static sjme_errorCode
sjme_class_fieldInfoClose(
136 sjme_attrInNotNull sjme_closeable closeable
)
138 sjme_errorCode error
;
139 sjme_class_fieldInfo info
;
143 info
= (sjme_class_fieldInfo
)closeable
;
145 return SJME_ERROR_NULL_ARGUMENTS
;
147 SJME_CLEANUP_CLOSE(info
->name
);
148 SJME_CLEANUP_CLOSE(info
->type
);
151 return SJME_ERROR_NONE
;
154 static sjme_errorCode
sjme_class_methodInfoClose(
155 sjme_attrInNotNull sjme_closeable closeable
)
157 sjme_errorCode error
;
158 sjme_class_methodInfo info
;
162 info
= (sjme_class_methodInfo
)closeable
;
164 return SJME_ERROR_NULL_ARGUMENTS
;
166 SJME_CLEANUP_CLOSE(info
->name
);
167 SJME_CLEANUP_CLOSE(info
->type
);
168 SJME_CLEANUP_CLOSE(info
->code
);
171 return SJME_ERROR_NONE
;
174 static sjme_errorCode
sjme_desc_identifierClose(
175 sjme_attrInNotNull sjme_closeable closeable
)
177 sjme_errorCode error
;
178 sjme_desc_identifier info
;
181 info
= (sjme_desc_identifier
)closeable
;
183 return SJME_ERROR_NULL_ARGUMENTS
;
185 SJME_CLEANUP_CLOSE(info
->whole
);
188 return SJME_ERROR_NONE
;
191 static sjme_errorCode
sjme_rom_libraryClose(
192 sjme_attrInNotNull sjme_closeable closeable
)
194 sjme_errorCode error
;
195 sjme_rom_library inLibrary
;
197 /* Recover library. */
198 inLibrary
= (sjme_rom_library
)closeable
;
199 if (inLibrary
== NULL
)
200 return SJME_ERROR_NULL_ARGUMENTS
;
202 /* Delete the prefix if there is one. */
203 if (inLibrary
->prefix
!= NULL
)
206 if (sjme_error_is(error
= sjme_alloc_free(
207 (sjme_pointer
)inLibrary
->prefix
)))
208 return sjme_error_default(error
);
211 inLibrary
->prefix
= NULL
;
214 /* Delete name if there is one. */
215 if (inLibrary
->name
!= NULL
)
218 if (sjme_error_is(error
= sjme_alloc_free(
219 (sjme_pointer
)inLibrary
->name
)))
220 return sjme_error_default(error
);
223 inLibrary
->name
= NULL
;
226 /* Forward close handler. */
227 if (inLibrary
->functions
->close
!= NULL
)
228 return inLibrary
->functions
->close(inLibrary
);
231 return SJME_ERROR_NONE
;
234 static sjme_errorCode
sjme_rom_suiteClose(
235 sjme_attrInNotNull sjme_closeable closeable
)
237 if (closeable
== NULL
)
238 return SJME_ERROR_NULL_ARGUMENTS
;
241 return sjme_error_notImplemented(0);
244 static sjme_errorCode
sjme_stringPool_close(
245 sjme_attrInNullable sjme_closeable closeable
)
247 sjme_errorCode error
;
248 sjme_stringPool stringPool
;
250 sjme_list_sjme_stringPool_string
* strings
;
251 sjme_stringPool_string target
;
254 stringPool
= (sjme_stringPool
)closeable
;
255 if (stringPool
== NULL
)
256 return SJME_ERROR_NULL_ARGUMENTS
;
258 /* Loaded string cleanup. */
259 SJME_CLEANUP_LIST(stringPool
->strings
);
262 return SJME_ERROR_NONE
;
265 static sjme_errorCode
sjme_stringPool_stringClose(
266 sjme_attrInNotNull sjme_closeable closeable
)
268 sjme_errorCode error
;
269 sjme_stringPool_string info
;
272 info
= (sjme_stringPool_string
)closeable
;
274 return SJME_ERROR_NULL_ARGUMENTS
;
277 return SJME_ERROR_NONE
;
280 /* ------------------------------------------------------------------------ */
282 sjme_errorCode
sjme_nvm_allocR(
283 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
284 sjme_attrInPositiveNonZero sjme_jint allocSize
,
285 sjme_attrInValue sjme_nvm_structType inType
,
286 sjme_attrOutNotNull sjme_nvm_common
* outCommon
287 SJME_DEBUG_ONLY_COMMA SJME_DEBUG_DECL_FILE_LINE_FUNC_OPTIONAL
)
289 sjme_errorCode error
;
290 sjme_closeable_closeHandlerFunc handler
;
291 sjme_nvm_common result
;
293 if (inPool
== NULL
|| outCommon
== NULL
)
294 return SJME_ERROR_NULL_ARGUMENTS
;
296 if (inType
<= SJME_NVM_STRUCT_UNKNOWN
||
297 inType
>= SJME_NVM_NUM_STRUCT
)
298 return SJME_ERROR_INVALID_ARGUMENT
;
300 /* Which handler is used? */
304 case SJME_NVM_STRUCT_CLASS_INFO
:
305 handler
= sjme_class_classInfoClose
;
308 case SJME_NVM_STRUCT_CODE
:
309 handler
= sjme_class_codeInfoClose
;
312 case SJME_NVM_STRUCT_FIELD_INFO
:
313 handler
= sjme_class_fieldInfoClose
;
316 case SJME_NVM_STRUCT_IDENTIFIER
:
317 handler
= sjme_desc_identifierClose
;
320 case SJME_NVM_STRUCT_METHOD_INFO
:
321 handler
= sjme_class_methodInfoClose
;
324 case SJME_NVM_STRUCT_POOL
:
325 handler
= sjme_class_constantPoolClose
;
328 case SJME_NVM_STRUCT_ROM_LIBRARY
:
329 handler
= sjme_rom_libraryClose
;
332 case SJME_NVM_STRUCT_ROM_SUITE
:
333 handler
= sjme_rom_suiteClose
;
336 case SJME_NVM_STRUCT_STRING_POOL
:
337 handler
= sjme_stringPool_close
;
340 case SJME_NVM_STRUCT_STRING_POOL_STRING
:
341 handler
= sjme_stringPool_stringClose
;
345 sjme_todo("Impl? %d", inType
);
346 return sjme_error_notImplemented(0);
349 /* Allocate result. */
351 #if defined(SJME_CONFIG_DEBUG)
352 if (sjme_error_is(error
= sjme_closeable_allocR(inPool
,
353 allocSize
, handler
, SJME_JNI_TRUE
,
354 SJME_AS_CLOSEABLEP(&result
), file
, line
, func
)) ||
357 if (sjme_error_is(error
= sjme_closeable_alloc(inPool
,
358 allocSize
, handler
, SJME_JNI_TRUE
,
359 SJME_AS_CLOSEABLEP(&result
))) || result
== NULL
)
361 return sjme_error_default(error
);
364 result
->type
= inType
;
368 return SJME_ERROR_NONE
;