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 // -------------------------------------------------------------------------*/
11 * Handling of classes.
16 #ifndef SQUIRRELJME_CLASSY_H
17 #define SQUIRRELJME_CLASSY_H
19 #include "sjme/nvm/nvm.h"
20 #include "sjme/nvm/stringPool.h"
21 #include "sjme/seekable.h"
22 #include "sjme/list.h"
23 #include "sjme/nvm/descriptor.h"
24 #include "sjme/stream.h"
28 #ifndef SJME_CXX_IS_EXTERNED
29 #define SJME_CXX_IS_EXTERNED
30 #define SJME_CXX_SQUIRRELJME_CLASSY_H
32 #endif /* #ifdef SJME_CXX_IS_EXTERNED */
33 #endif /* #ifdef __cplusplus */
35 /*--------------------------------------------------------------------------*/
38 * The version of the class.
42 typedef enum sjme_class_version
44 /** CLDC 1.1 (JSR 30). */
45 SJME_CLASS_CLDC_1_0
= 2949123,
47 /** CLDC 1.1 (JSR 139). */
48 SJME_CLASS_CLDC_1_1
= 3080192,
51 SJME_CLASS_CLDC_1_8
= 3342336,
55 * Core class information structure.
59 typedef struct sjme_class_infoCore sjme_class_infoCore
;
62 * Opaque class information structure.
66 typedef struct sjme_class_infoCore
* sjme_class_info
;
69 * Opaque constant pool information.
73 typedef struct sjme_class_poolInfoCore sjme_class_poolInfoCore
;
76 * A @c SJME_CLASS_POOL_TYPE_CLASS which represents a class or interface.
80 typedef struct sjme_class_poolEntryClass sjme_class_poolEntryClass
;
83 * Opaque constant pool information.
87 typedef sjme_class_poolInfoCore
* sjme_class_poolInfo
;
90 * Core method information structure.
94 typedef struct sjme_class_methodInfoCore sjme_class_methodInfoCore
;
97 * Opaque method information structure.
101 typedef struct sjme_class_methodInfoCore
* sjme_class_methodInfo
;
108 SJME_LIST_DECLARE(sjme_class_methodInfo
, 0);
110 /** The basic type of @c sjme_class_methodInfo . */
111 #define SJME_TYPEOF_BASIC_sjme_class_methodInfo \
112 SJME_BASIC_TYPE_ID_OBJECT
115 * Core field information structure.
119 typedef struct sjme_class_fieldInfoCore sjme_class_fieldInfoCore
;
122 * Opaque field information structure.
126 typedef struct sjme_class_fieldInfoCore
* sjme_class_fieldInfo
;
133 SJME_LIST_DECLARE(sjme_class_fieldInfo
, 0);
135 /** The basic type of @c sjme_class_fieldInfo . */
136 #define SJME_TYPEOF_BASIC_sjme_class_fieldInfo \
137 SJME_BASIC_TYPE_ID_OBJECT
140 * Exception handling information.
144 typedef struct sjme_class_exceptionHandler
146 /** The range of the exception where it applies. */
147 sjme_rangeShort range
;
149 /** The handler PC address. */
150 sjme_jshort handlerPc
;
152 /** The type that this catches. */
153 sjme_class_poolEntryClass
* handles
;
154 } sjme_class_exceptionHandler
;
156 /** A list of exceptions. */
157 SJME_LIST_DECLARE(sjme_class_exceptionHandler
, 0);
159 /** The basic type of @c sjme_class_exceptionHandler . */
160 #define SJME_TYPEOF_BASIC_sjme_class_exceptionHandler \
161 SJME_BASIC_TYPE_ID_OBJECT
164 * Method code information structure.
168 typedef struct sjme_class_codeInfoCore sjme_class_codeInfoCore
;
171 * Opaque method code structure.
175 typedef struct sjme_class_codeInfoCore
* sjme_class_codeInfo
;
182 typedef struct sjme_class_accessFlags
184 /** Is this public? */
185 sjme_jboolean
public : 1;
187 /** Is this protected? */
188 sjme_jboolean
protected : 1;
190 /** Is this private? */
191 sjme_jboolean
private : 1;
192 } sjme_class_accessFlags
;
199 typedef struct sjme_class_classFlags
202 sjme_class_accessFlags access
;
204 /** Is the class final? */
205 sjme_jboolean final
: 1;
207 /** Is the class super? */
208 sjme_jboolean super
: 1;
210 /** Is the class an interface? */
211 sjme_jboolean interface
: 1;
213 /** Is the class abstract? */
214 sjme_jboolean abstract
: 1;
216 /** Is the class synthetic? */
217 sjme_jboolean synthetic
: 1;
219 /** Is the class an annotation? */
220 sjme_jboolean annotation
: 1;
222 /** Is the class an enum? */
223 sjme_jboolean enumeration
: 1;
224 } sjme_class_classFlags
;
227 * Common member flags.
231 typedef struct sjme_class_memberFlags
234 sjme_class_accessFlags access
;
236 /** Static member? */
237 sjme_jboolean isStatic
: 1;
240 sjme_jboolean final
: 1;
242 /** Synthetic member? */
243 sjme_jboolean synthetic
: 1;
244 } sjme_class_memberFlags
;
251 typedef struct sjme_class_fieldFlags
253 /** Common member flags. */
254 sjme_class_memberFlags member
;
256 /** Is this volatile? */
257 sjme_jboolean isVolatile
: 1;
259 /** Is this transient? */
260 sjme_jboolean transient
: 1;
262 /** Is this an enumeration. */
263 sjme_jboolean enumeration
: 1;
264 } sjme_class_fieldFlags
;
271 typedef struct sjme_class_methodFlags
273 /** Common member flags. */
274 sjme_class_memberFlags member
;
276 /** Synchronized, monitor entry/exit on call? */
277 sjme_jboolean synchronized
: 1;
279 /** Bridge method, generated by the compiler? */
280 sjme_jboolean bridge
: 1;
282 /** Variadic arguments? */
283 sjme_jboolean varargs
: 1;
285 /** Is this a native method? */
286 sjme_jboolean native
: 1;
289 sjme_jboolean abstract
: 1;
291 /** Strict floating point? */
292 sjme_jboolean strictfp
: 1;
293 } sjme_class_methodFlags
;
296 * The type that a constant pool entry may be.
300 typedef enum sjme_class_poolType
303 SJME_CLASS_POOL_TYPE_NULL
= 0,
306 SJME_CLASS_POOL_TYPE_UTF
= 1,
309 SJME_CLASS_POOL_TYPE_UNUSED_2
= 2,
311 /** Integer constant. */
312 SJME_CLASS_POOL_TYPE_INTEGER
= 3,
314 /** Float constant. */
315 SJME_CLASS_POOL_TYPE_FLOAT
= 4,
317 /** Long constant. */
318 SJME_CLASS_POOL_TYPE_LONG
= 5,
320 /** Double constant. */
321 SJME_CLASS_POOL_TYPE_DOUBLE
= 6,
323 /** Class constant. */
324 SJME_CLASS_POOL_TYPE_CLASS
= 7,
326 /** String constant. */
327 SJME_CLASS_POOL_TYPE_STRING
= 8,
329 /** Field reference. */
330 SJME_CLASS_POOL_TYPE_FIELD
= 9,
332 /** Method reference. */
333 SJME_CLASS_POOL_TYPE_METHOD
= 10,
335 /** Interface method reference. */
336 SJME_CLASS_POOL_TYPE_INTERFACE_METHOD
= 11,
338 /** Name and type. */
339 SJME_CLASS_POOL_TYPE_NAME_AND_TYPE
= 12,
342 SJME_CLASS_POOL_TYPE_UNUSED_13
= 13,
345 SJME_CLASS_POOL_TYPE_UNUSED_14
= 14,
347 /** Method handle. */
348 SJME_CLASS_POOL_TYPE_METHOD_HANDLE
= 15,
351 SJME_CLASS_POOL_TYPE_METHOD_TYPE
= 16,
354 SJME_CLASS_POOL_TYPE_UNUSED_17
= 17,
356 /** Invoke dynamic. */
357 SJME_CLASS_POOL_TYPE_INVOKE_DYNAMIC
= 18,
359 /** The number of pool types. */
360 SJME_NUM_CLASS_POOL_TYPE
361 } sjme_class_poolType
;
363 struct sjme_class_poolEntryClass
365 /** The type of entry that this is. */
366 sjme_class_poolType type
;
368 /** The index where the descriptor is located. */
369 sjme_jshort descriptorIndex
;
371 /** The descriptor this represents. */
372 sjme_stringPool_string descriptor
;
376 * A @c SJME_CLASS_POOL_TYPE_DOUBLE which represents a double constant.
380 typedef struct sjme_class_poolEntryDouble
382 /** The type of entry that this is. */
383 sjme_class_poolType type
;
385 /** The constant value. */
387 } sjme_class_poolEntryDouble
;
390 * A @c SJME_CLASS_POOL_TYPE_NAME_AND_TYPE which represents a name and type
391 * of a member without the class.
395 typedef struct sjme_class_poolEntryNameAndType sjme_class_poolEntryNameAndType
;
398 * Either @c SJME_CLASS_POOL_TYPE_FIELD , @c SJME_CLASS_POOL_TYPE_METHOD ,
399 * or @c SJME_CLASS_POOL_TYPE_INTERFACE_METHOD which represents a reference
404 typedef struct sjme_class_poolEntryMember
406 /** The type of entry that this is. */
407 sjme_class_poolType type
;
409 /** The index where the class is located. */
410 sjme_jshort inClassIndex
;
412 /** The class this refers to. */
413 const sjme_class_poolEntryClass
* inClass
;
415 /** The index where the name and type is located. */
416 sjme_jshort nameAndTypeIndex
;
418 /** The name and type used. */
419 const sjme_class_poolEntryNameAndType
* nameAndType
;
420 } sjme_class_poolEntryMember
;
423 * A @c SJME_CLASS_POOL_TYPE_FLOAT which represents a float constant.
427 typedef struct sjme_class_poolEntryFloat
429 /** The type of entry that this is. */
430 sjme_class_poolType type
;
432 /** The constant value. */
434 } sjme_class_poolEntryFloat
;
437 * A @c SJME_CLASS_POOL_TYPE_INTEGER which represents an integer constant.
441 typedef struct sjme_class_poolEntryInteger
443 /** The type of entry that this is. */
444 sjme_class_poolType type
;
446 /** The constant value. */
448 } sjme_class_poolEntryInteger
;
451 * A @c SJME_CLASS_POOL_TYPE_LONG which represents a long constant.
455 typedef struct sjme_class_poolEntryLong
457 /** The type of entry that this is. */
458 sjme_class_poolType type
;
460 /** The constant value. */
462 } sjme_class_poolEntryLong
;
465 * A @c SJME_CLASS_POOL_TYPE_STRING which represents a string constant.
469 typedef struct sjme_class_poolEntryString
471 /** The type of entry that this is. */
472 sjme_class_poolType type
;
474 /** The index where the value is located. */
475 sjme_jshort valueIndex
;
478 sjme_stringPool_string value
;
479 } sjme_class_poolEntryString
;
481 struct sjme_class_poolEntryNameAndType
483 /** The type of entry that this is. */
484 sjme_class_poolType type
;
486 /** The index where the name is located. */
487 sjme_jshort nameIndex
;
490 sjme_stringPool_string name
;
492 /** The index where the descriptor is located. */
493 sjme_jshort descriptorIndex
;
496 sjme_stringPool_string descriptor
;
500 * A @c SJME_CLASS_POOL_TYPE_UTF which is a modified UTF-8 entry.
504 typedef struct sjme_class_poolEntryUtf
506 /** The type of entry that this is. */
507 sjme_class_poolType type
;
509 /** The UTF data for this entry. */
510 sjme_stringPool_string utf
;
511 } sjme_class_poolEntryUtf
;
514 * Represents a single constant pool entry.
518 typedef union sjme_class_poolEntry
520 /** The type of entry that this is. */
521 sjme_class_poolType type
;
524 sjme_class_poolEntryClass classRef
;
527 sjme_class_poolEntryDouble constDouble
;
530 sjme_class_poolEntryFloat constFloat
;
533 sjme_class_poolEntryInteger constInteger
;
536 sjme_class_poolEntryLong constLong
;
538 /** String constant. */
539 sjme_class_poolEntryString constString
;
541 /** A class member. */
542 sjme_class_poolEntryMember member
;
544 /** Name and type. */
545 sjme_class_poolEntryNameAndType nameAndType
;
547 /** UTF pool entry. */
548 sjme_class_poolEntryUtf utf
;
549 } sjme_class_poolEntry
;
551 /** A list of constant pool entries. */
552 SJME_LIST_DECLARE(sjme_class_poolEntry
, 0);
554 struct sjme_class_poolInfoCore
556 /** The common NanoCoat base. */
557 sjme_nvm_commonBase common
;
559 /** Constant pool entries. */
560 sjme_list_sjme_class_poolEntry
* pool
;
563 struct sjme_class_infoCore
565 /** The common NanoCoat base. */
566 sjme_nvm_commonBase common
;
568 /** The constant pool of this class. */
569 sjme_class_poolInfo pool
;
571 /** The class version. */
572 sjme_class_version version
;
575 sjme_class_classFlags flags
;
577 /** The name of this class. */
578 sjme_stringPool_string name
;
580 /** The superclass of this class. */
581 sjme_stringPool_string superName
;
583 /** The interfaces this class implements. */
584 const sjme_list_sjme_stringPool_string
* interfaceNames
;
586 /** Fields within the method. */
587 const sjme_list_sjme_class_fieldInfo
* fields
;
589 /** Methods within the class. */
590 const sjme_list_sjme_class_methodInfo
* methods
;
594 * Represents a field's constant value.
598 typedef struct sjme_class_fieldConstVal
600 /** The type of value. */
601 sjme_javaTypeId type
;
603 /** The value of the field. */
606 /** The Java value. */
609 /** Constant string. */
610 sjme_stringPool_string string
;
612 } sjme_class_fieldConstVal
;
614 struct sjme_class_fieldInfoCore
616 /** The class which contains this field. */
617 sjme_class_info inClass
;
620 sjme_class_fieldFlags flags
;
622 /** The name of this field. */
623 sjme_stringPool_string name
;
625 /** The type of this field. */
626 sjme_stringPool_string type
;
628 /** The constant value, if any. */
629 sjme_class_fieldConstVal constVal
;
632 struct sjme_class_methodInfoCore
634 /** The class which contains this method. */
635 sjme_class_info inClass
;
638 sjme_class_methodFlags flags
;
640 /** The name of this method. */
641 sjme_stringPool_string name
;
643 /** The type of this method. */
644 sjme_stringPool_string type
;
646 /** The method code, if it is not native. */
647 sjme_class_codeInfo code
;
650 struct sjme_class_codeInfoCore
652 /** The method which contains this code. */
653 sjme_class_methodInfo inMethod
;
655 /** Maximum number of locals. */
658 /** Maximum number of stack entries. */
661 /** Exception table. */
662 const sjme_list_sjme_class_exceptionHandler
* exceptions
;
664 /** Method byte code. */
665 sjme_list_sjme_jubyte code
;
669 * Stack map table representation.
673 typedef struct sjme_class_stackMap
677 } sjme_class_stackMap
;
680 * Handler function for attribute parsing.
682 * @param inPool The allocation pool.
683 * @param inConstPool The constant pool.
684 * @param inStringPool The string pool.
685 * @param context The passed context.
686 * @param attrName The name of the attribute.
687 * @param attrStream The stream over the attribute data.
688 * @param attrData The attribute data.
689 * @param attrLen The data length.
690 * @return Any resultant error, if any.
693 typedef sjme_errorCode (*sjme_class_parseAttributeHandlerFunc
)(
694 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
695 sjme_attrInNotNull sjme_class_poolInfo inConstPool
,
696 sjme_attrInNotNull sjme_stringPool inStringPool
,
697 sjme_attrInNotNull sjme_pointer context
,
698 sjme_attrInNotNull sjme_lpcstr attrName
,
699 sjme_attrInNotNull sjme_stream_input attrStream
,
700 sjme_attrInNotNullBuf(attrLen
) sjme_pointer attrData
,
701 sjme_attrInPositive sjme_jint attrLen
);
704 * Structure for attribute handlers according to their name and handler.
708 typedef struct sjme_class_parseAttributeHandlerInfo
710 /** The name to handle. */
713 /** The handler for the attribute. */
714 sjme_class_parseAttributeHandlerFunc handler
;
715 } sjme_class_parseAttributeHandlerInfo
;
718 * Parses a single class and loads its class information.
720 * @param inPool The pool to allocate within.
721 * @param inStream The stream to parse from when reading the class.
722 * @param inStringPool The pool for strings existing in memory already.
723 * @param outClass The resultant class information
724 * @return Any resultant error code, if any.
727 sjme_errorCode
sjme_class_parse(
728 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
729 sjme_attrInNotNull sjme_stream_input inStream
,
730 sjme_attrInNotNull sjme_stringPool inStringPool
,
731 sjme_attrOutNotNull sjme_class_info
* outClass
);
736 * @param inPool The allocation pool.
737 * @param inStream The stream to read from.
738 * @param inConstPool The constant pool.
739 * @param inStringPool The string pool.
740 * @param handlers The handler used for attribute parsing.
741 * @param context The context to pass to the handler.
742 * @return Any resultant error, if any.
745 sjme_errorCode
sjme_class_parseAttributes(
746 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
747 sjme_attrInNotNull sjme_stream_input inStream
,
748 sjme_attrInNotNull sjme_class_poolInfo inConstPool
,
749 sjme_attrInNotNull sjme_stringPool inStringPool
,
750 sjme_attrInNotNull
const sjme_class_parseAttributeHandlerInfo
* handlers
,
751 sjme_attrInNotNull sjme_pointer context
);
754 * Parses the constant pool of an input class.
756 * @param inPool The input pool.
757 * @param inStream The stream to read from.
758 * @param inStringPool The string pool for reused strings.
759 * @param outPool The resultant read constant pool.
760 * @return Any resultant error, if any.
763 sjme_errorCode
sjme_class_parseConstantPool(
764 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
765 sjme_attrInNotNull sjme_stream_input inStream
,
766 sjme_attrInNotNull sjme_stringPool inStringPool
,
767 sjme_attrOutNotNull sjme_class_poolInfo
* outPool
);
770 * Parses a single field.
772 * @param inPool The allocation pool to use.
773 * @param inStream The stream to read from.
774 * @param inConstPool The class constant pool.
775 * @param inStringPool The string pool used.
776 * @param outField The resultant field.
777 * @return Any resultant error, if any.
780 sjme_errorCode
sjme_class_parseField(
781 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
782 sjme_attrInNotNull sjme_stream_input inStream
,
783 sjme_attrInNotNull sjme_class_poolInfo inConstPool
,
784 sjme_attrInNotNull sjme_stringPool inStringPool
,
785 sjme_attrOutNotNull sjme_class_fieldInfo
* outField
);
788 * Parses a single method.
790 * @param inPool The allocation pool to use.
791 * @param inStream The stream to read from.
792 * @param inConstPool The class constant pool.
793 * @param inStringPool The string pool used.
794 * @param outMethod The resultant method.
795 * @return Any resultant error, if any.
798 sjme_errorCode
sjme_class_parseMethod(
799 sjme_attrInNotNull sjme_alloc_pool
* inPool
,
800 sjme_attrInNotNull sjme_stream_input inStream
,
801 sjme_attrInNotNull sjme_class_poolInfo inConstPool
,
802 sjme_attrInNotNull sjme_stringPool inStringPool
,
803 sjme_attrInOutNotNull sjme_class_methodInfo
* outMethod
);
805 /*--------------------------------------------------------------------------*/
809 #ifdef SJME_CXX_SQUIRRELJME_CLASSY_H
811 #undef SJME_CXX_SQUIRRELJME_CLASSY_H
812 #undef SJME_CXX_IS_EXTERNED
813 #endif /* #ifdef SJME_CXX_SQUIRRELJME_CLASSY_H */
814 #endif /* #ifdef __cplusplus */
816 #endif /* SQUIRRELJME_CLASSY_H */