// $Id: class.h,v 1.5 1999/02/01 17:43:05 shields Exp $ copyright notice #ifndef class_INCLUDED #define class_INCLUDED #include "config.h" #include <stdio.h> #include "semantic.h" #include "access.h" #include "unicode.h" #include "tuple.h" class cp_info { public: u1 tag; cp_info(u1 _tag) : tag(_tag) {} virtual ~cp_info() {} virtual void put(OutputBuffer &output_buffer) { assert("trying to put unsupported attribute kind" == NULL); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << (int) tag; } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << (int) tag; } #endif }; class CONSTANT_Class_info : public cp_info { public: /* u1 tag; */ u2 name_index; CONSTANT_Class_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Class_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(name_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Class_info: name_index " << name_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "Class:"; constant_pool[name_index]->describe(constant_pool); } #endif }; class CONSTANT_Double_info : public cp_info { public: /* u1 tag; */ u4 high_bytes; u4 low_bytes; CONSTANT_Double_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Double_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB4(high_bytes); output_buffer.PutB4(low_bytes); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Float_info: bytes \n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "D:"; // constant_pool[string_index]->describe(constant_pool); } #endif }; class CONSTANT_Fieldref_info : public cp_info { public: /* u1 tag; */ u2 class_index; u2 name_and_type_index; CONSTANT_Fieldref_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Fieldref_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(class_index); output_buffer.PutB2(name_and_type_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Fieldref_info: class_index: " << class_index << ", name_and_type_index: " << name_and_type_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { constant_pool[class_index]->describe(constant_pool); cout << "."; constant_pool[name_and_type_index]->describe(constant_pool); } #endif }; class CONSTANT_Float_info : public cp_info { public: /* u1 tag; */ u4 bytes; CONSTANT_Float_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Float_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB4(bytes); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Float_info: bytes " << (float) bytes << "\n"; //DSDouble } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "F:"; // constant_pool[string_index]->describe(constant_pool); } #endif }; class CONSTANT_Integer_info : public cp_info { public: /* u1 tag; */ u4 bytes; CONSTANT_Integer_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Integer_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB4(bytes); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { int val; val = ((bytes>>24)&0xff)<<24 | ((bytes>>16)&0xff)<<16 | ((bytes>>8)&0xff)<<8 | (bytes&0xff); // cout << "CONSTANT_Integer_info: bytes " << value << "\n"; cout << "CONSTANT_Integer_info: bytes " << val << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "I:"; // constant_pool[string_index]->describe(constant_pool); } #endif }; class CONSTANT_InterfaceMethodref_info : public cp_info { public: /* u1 tag; */ u2 class_index; u2 name_and_type_index; CONSTANT_InterfaceMethodref_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_InterfaceMethodref_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(class_index); output_buffer.PutB2(name_and_type_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_InterfaceMethodref_info: class_index: " << class_index << ", name_and_type_index: " << name_and_type_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { constant_pool[class_index]->describe(constant_pool); cout << "."; constant_pool[name_and_type_index]->describe(constant_pool); } #endif }; class CONSTANT_Long_info : public cp_info { public: /* u1 tag; */ u4 high_bytes; u4 low_bytes; CONSTANT_Long_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Long_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB4(high_bytes); output_buffer.PutB4(low_bytes); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Long_info: bytes \n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "L:"; // constant_pool[string_index]->describe(constant_pool); } #endif }; class CONSTANT_Methodref_info : public cp_info { public: /* u1 tag; */ u2 class_index; u2 name_and_type_index; CONSTANT_Methodref_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Methodref_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(class_index); output_buffer.PutB2(name_and_type_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Methodref_info: class_index: " << class_index << ", name_and_type_index: " << name_and_type_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { constant_pool[class_index]->describe(constant_pool); cout << "."; constant_pool[name_and_type_index]->describe(constant_pool); } #endif }; class CONSTANT_NameAndType_info : public cp_info { public: /* u1 tag; */ u2 name_index; u2 descriptor_index; CONSTANT_NameAndType_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_NameAndType_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(name_index); output_buffer.PutB2(descriptor_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_NameAndType_info: name_index: " << name_index << ", descriptor_index: " << descriptor_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { constant_pool[name_index]->describe(constant_pool); cout << " "; constant_pool[descriptor_index]->describe(constant_pool); } #endif }; class CONSTANT_String_info : public cp_info { public: /* u1 tag; */ u2 string_index; CONSTANT_String_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_String_info() {} virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(string_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_String_info: string_index: " << string_index << "\n"; } virtual void describe(Tuple<cp_info *>& constant_pool) { constant_pool[string_index]->describe(constant_pool); } #endif }; class CONSTANT_Utf8_info : public cp_info { public: /* u1 tag; */ u2 length() { return length_; } char *bytes; /* bytes[length+1] ... after input a '\0' will be added. */ CONSTANT_Utf8_info(u1 _tag) : cp_info(_tag) {} virtual ~CONSTANT_Utf8_info() { delete [] bytes; } virtual void put(OutputBuffer &output_buffer) { output_buffer.PutB1(tag); output_buffer.PutB2(length()); for (int i = 0; i < length(); i++) output_buffer.PutB1(bytes[i]); } public: u2 length_; #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "CONSTANT_Utf8_info: length: " << length_<< " "; for (int i=0;i<length_;i++) Unicode::Cout(bytes[i]); cout << "\n"; // should only do packing when actually write the string out!! // so have same common internal form on input and output. } virtual void describe(Tuple<cp_info *>& constant_pool) { cout << "\""; for (int i=0;i<length_;i++) Unicode::Cout(bytes[i]); cout << "\""; // Unicode::Cout(bytes); } #endif }; // field_info and method_infoshould be defined here, but they contain attributes, so it is necessary // to define the attributes first. class attribute_info { public: enum { Generic, Code, ConstantValue, Deprecated, Exceptions, InnerClasses, LineNumberTable, LocalVariableTable, SourceFile, Synthetic }; u1 tag; u2 attribute_name_index; u4 attribute_length; attribute_info(u1 _tag) : tag(_tag) {} attribute_info(u1 _tag, u2 _name_index, u4 _length) : tag(_tag), attribute_name_index(_name_index), attribute_length(_length) {} virtual ~attribute_info() {}; virtual void put(OutputBuffer &output_buffer) { assert(0); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "print for attribute info tag " << tag << " not defined\n"; } #endif }; class GenericAttribute_info : public attribute_info { public: // u2 attribute_name_index; u4 attribute_length() { return info.Length(); } Tuple<u1> info; /* info[attribute_length] */ GenericAttribute_info(u2 &_name_index, u4 &_length) : attribute_info(Generic, _name_index, _length), info(8, 4) {} virtual ~GenericAttribute_info() { } virtual void put(OutputBuffer &output_error) { assert(0); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "print for attribute info tag " << tag << " not defined\n"; } #endif }; class Code_attribute : public attribute_info { public: Code_attribute() : attribute_info(Code,0,0), max_stack(0), max_locals(0), code(8, 4), exception_table(6, 16), attributes(6, 16) {} Code_attribute(u2 &_name_index, u4 &_length) : attribute_info(Code,_name_index,_length), code(8, 4), exception_table(6, 16), attributes(6, 16) {} virtual ~Code_attribute() { for (int i = 0; i < attributes.Length(); i++) delete attributes[i]; } // u2 attribute_name_index; // u4 attribute_length; u2 max_stack; u2 max_locals; /* u4 code_length; */ Tuple<u1> code; /* code[code_length] */ u2 exception_table_length() { return exception_table.Length(); } struct exception_element { u2 start_pc; u2 end_pc; u2 handler_pc; u2 catch_type; }; Tuple<exception_element> exception_table; /* exceptiontable[exception_table_length] */ u2 attributes_count() { return attributes.Length(); } Tuple<attribute_info *> attributes; /* attributes[attributes_count] */ virtual void put(OutputBuffer &output_buffer) { int i; assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(max_stack); output_buffer.PutB2(max_locals); output_buffer.PutB4(code.Length()); for (i = 0; i < code.Length(); i++) output_buffer.PutB1(code[i]); output_buffer.PutB2(exception_table.Length()); for (i = 0; i < exception_table.Length(); i++) { output_buffer.PutB2(exception_table[i].start_pc); output_buffer.PutB2(exception_table[i].end_pc); output_buffer.PutB2(exception_table[i].handler_pc); output_buffer.PutB2(exception_table[i].catch_type); } output_buffer.PutB2(attributes.Length()); for (i = 0; i < attributes.Length(); i++) attributes[i] -> put(output_buffer); return; } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { void opdmp(Tuple<cp_info *>& constant_pool, Tuple<u1>& code); int i; cout << "Code_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << "\n"; cout << " max_stack " << max_stack << " max_locals " << max_locals << " code_length " << code.Length() << "\n"; if (exception_table.Length()) { cout << " exception_table: " << exception_table.Length() << " entries\n"; for (i=0; i<exception_table.Length(); i++) { cout << " start_pc " << exception_table[i].start_pc << " end_pc " << exception_table[i].end_pc << " handler_pc " << exception_table[i].handler_pc << " catch_type " << exception_table[i].catch_type << "\n"; // const_string(cp,exception_table[i].catch_type); } } opdmp(constant_pool,code); cout << " \n"; for (i=0;i<attributes.Length();i++) { attributes[i] -> print(constant_pool); } } #endif }; class ConstantValue_attribute : public attribute_info { public: ConstantValue_attribute(u2 &_name_index, u4 &_length) : attribute_info(ConstantValue,_name_index,_length) {} // u2 attribute_name_index; // u4 attribute_length; /* must be 2 */ u2 constantvalue_index; virtual ~ConstantValue_attribute() {} virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(constantvalue_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "ConstantValue_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << " constantvalue_index " << constantvalue_index << "\n"; } #endif }; class Deprecated_attribute : public attribute_info { public: // u2 attribute_name_index; // u4 attribute_length; /* must be 0 */ Deprecated_attribute(u2 &_name_index, u4 &_length) : attribute_info(Deprecated,_name_index,_length) {} virtual ~Deprecated_attribute() {} #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "Deprecated_attribute attribute_name_index " << attribute_name_index << " length " << attribute_length << "\n"; } #endif }; class Exceptions_attribute : public attribute_info { public: // u2 attribute_name_index; // u4 attribute_length; /* must be 2 */ u2 number_of_exceptions() { return exception_index_table.Length(); } Tuple<u2> exception_index_table; /* exception_index_table[number_of_exceptions] */ Exceptions_attribute(u2 &_name_index, u4 &_length) : attribute_info(Exceptions,_name_index, _length) {} virtual ~Exceptions_attribute() { } virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(exception_index_table.Length()); for (int i = 0; i< exception_index_table.Length(); i++) output_buffer.PutB2(exception_index_table[i]); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "Exceptions_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << "\n"; for (int i=0; i<exception_index_table.Length(); i++) { cout << " " << exception_index_table[i]; } cout << "\n"; } #endif }; class InnerClasses_attribute : public attribute_info { public: InnerClasses_attribute(u2 &_name_index, u4 &_length) : attribute_info(InnerClasses,_name_index,_length), inner_classes(6, 16) {} virtual ~InnerClasses_attribute() {} // u2 attribute_name_index; // u4 attribute_length; u2 inner_classes_length() { return inner_classes.Length();} struct inner_classes_element { u2 inner_class_info_index; u2 outer_class_info_index; u2 inner_name_index; u2 inner_class_access_flags; }; Tuple<inner_classes_element> inner_classes; /* inner_classes_table[inner_classes_table_length] */ virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(inner_classes.Length()); for (int i = 0; i < inner_classes.Length(); i++) { output_buffer.PutB2(inner_classes[i].inner_class_info_index); output_buffer.PutB2(inner_classes[i].outer_class_info_index); output_buffer.PutB2(inner_classes[i].inner_name_index); output_buffer.PutB2(inner_classes[i].inner_class_access_flags); } } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "InnerClasses_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << "\n"; cout << " inner_classes_length " << inner_classes.Length() <<"\n"; for (int i=0; i<inner_classes.Length(); i++) { cout << " " << i << " inner_class_info_index " << inner_classes[i].inner_class_info_index << " outer_class_info_index " << inner_classes[i].outer_class_info_index << " inner_name_index " << inner_classes[i].inner_name_index << " inner_class_access_flags " << inner_classes[i].inner_class_access_flags << "\n"; } } #endif }; class LineNumberTable_attribute : public attribute_info { public: LineNumberTable_attribute(u2 &_name_index, u4 &_length) : attribute_info(LineNumberTable,_name_index,_length), line_number_table(6, 16) {} // u2 attribute_name_index; // u4 attribute_length; u2 line_number_table_length() { return line_number_table.Length();} struct line_number_element { u2 start_pc; u2 line_number; }; Tuple<line_number_element> line_number_table; /* line_number_table[line_number_table_length] */ virtual ~LineNumberTable_attribute() {} virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(line_number_table.Length()); for (int i = 0; i < line_number_table.Length(); i++) { output_buffer.PutB2(line_number_table[i].start_pc); output_buffer.PutB2(line_number_table[i].line_number); } } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "LineNumberTable_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << "\n"; cout << " line_number_table_length " << line_number_table.Length() <<"\n"; for (int i=0; i<line_number_table.Length(); i++) { cout << " " << i << " start_pc " << line_number_table[i].start_pc << " line_number " << line_number_table[i].line_number << "\n"; } } #endif }; class LocalVariableTable_attribute : public attribute_info { public: LocalVariableTable_attribute(u2 &_name_index, u4 &_length) : attribute_info(LocalVariableTable,_name_index,_length) {} // u2 attribute_name_index; // u4 attribute_length; u2 local_variable_table_length() { return local_variable_table.Length();} struct local_variable_element { u2 start_pc; u2 length; u2 name_index; u2 descriptor_index; u2 index; }; Tuple<local_variable_element> local_variable_table; /* local_variable_table[local_variable_table_length] */ virtual ~LocalVariableTable_attribute() { } virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(local_variable_table.Length()); for (int i = 0; i < local_variable_table.Length(); i++) { output_buffer.PutB2(local_variable_table[i].start_pc); output_buffer.PutB2(local_variable_table[i].length); output_buffer.PutB2(local_variable_table[i].name_index); output_buffer.PutB2(local_variable_table[i].descriptor_index); output_buffer.PutB2(local_variable_table[i].index); } } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "LocalVariableTable_attribute attribute_name_index " << attribute_name_index << " attribute_length " << attribute_length << "\n"; cout << " local_variable_table_length " << local_variable_table.Length() <<"\n"; for (int i=0; i<local_variable_table.Length(); i++) { cout << " " << i << " start_pc " << local_variable_table[i].start_pc << " length " << local_variable_table[i].length << " name_index " << local_variable_table[i].name_index << " descriptor_index " << local_variable_table[i].descriptor_index << " index " << local_variable_table[i].index << "\n"; } } #endif }; class SourceFile_attribute : public attribute_info { public: // u2 attribute_name_index; // u4 attribute_length; /* must be 2 */ u2 sourcefile_index; SourceFile_attribute(u2 &_name_index, u4 &_length) : attribute_info(SourceFile,_name_index,_length) {} virtual ~SourceFile_attribute() {} virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); output_buffer.PutB2(sourcefile_index); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "SourceFile_attribute attribute_name_index " << attribute_name_index << " length " << attribute_length << " sourcefile_index " << sourcefile_index << "\n"; } #endif }; class Synthetic_attribute : public attribute_info { public: // u2 attribute_name_index; // u4 attribute_length; /* must be 0 */ Synthetic_attribute(u2 &_name_index, u4 &_length) : attribute_info(Synthetic,_name_index,_length) {} virtual ~Synthetic_attribute() {} virtual void put(OutputBuffer &output_buffer) { assert(attribute_name_index != 0); output_buffer.PutB2(attribute_name_index); output_buffer.PutB4(attribute_length); } #ifdef TEST virtual void print(Tuple<cp_info *>& constant_pool) { cout << "Synthetic_attribute attribute_name_index " << attribute_name_index << " length " << attribute_length << "\n"; } #endif }; class field_info : public AccessFlags { public: /* u2 access_flags; */ u2 name_index; u2 descriptor_index; u2 attributes_count() { return attributes.Length();} Tuple<attribute_info *> attributes; /* attributes[attributes_count] */ ~field_info() { for (int i = 0; i < attributes.Length(); i++) delete attributes[i]; } inline void put(OutputBuffer &output_buffer) { output_buffer.PutB2(access_flags); output_buffer.PutB2(name_index); output_buffer.PutB2(descriptor_index); output_buffer.PutB2(attributes.Length()); for (int ai = 0; ai < attributes.Length(); ai++) attributes[ai] -> put(output_buffer); } #ifdef TEST void print(Tuple<cp_info *>& constant_pool) { cout << "field_info name_index " << name_index << " descriptor_index " << descriptor_index << "\n"; AccessFlags::Print(); for (int i=0; i<attributes.Length(); i++) { attributes[i]->print(constant_pool); } cout << "\n"; } #endif }; class method_info : public AccessFlags { public: /* u2 access_flags; */ u2 name_index; u2 descriptor_index; u2 attributes_count() { return attributes.Length(); } Tuple<attribute_info *> attributes; /* attributes[attributes_count] */ ~method_info() { for (int i = 0; i < attributes.Length(); i++) delete attributes[i]; } inline void put(OutputBuffer &output_buffer) { output_buffer.PutB2(access_flags); output_buffer.PutB2(name_index); output_buffer.PutB2(descriptor_index); output_buffer.PutB2(attributes.Length()); for (int ai = 0; ai < attributes.Length(); ai++) attributes[ai] -> put(output_buffer); } #ifdef TEST void print(Tuple<cp_info *>& constant_pool) { cout << "method_info name_index " << name_index << " descriptor_index " << descriptor_index << "\n"; AccessFlags::Print(); for (int i=0; i<attributes.Length(); i++) { attributes[i]->print(constant_pool); } cout << "\n"; } #endif }; class ClassFile : public AccessFlags { public: enum { CONSTANT_Class = 7, CONSTANT_Fieldref = 9, CONSTANT_Methodref = 10, CONSTANT_InterfaceMethodref = 11, CONSTANT_String = 8, CONSTANT_Integer = 3, CONSTANT_Float = 4, CONSTANT_Long = 5, CONSTANT_Double = 6, CONSTANT_NameAndType = 12, CONSTANT_Utf8 = 1 }; u4 magic; u2 minor_version; u2 major_version; u2 constant_pool_count() { return constant_pool.Length(); } Tuple<cp_info *> constant_pool; /* cp_info[constant_pool_count] */ /* u2 access_flags; */ u2 this_class; u2 super_class; u2 interfaces_count() { return interfaces.Length(); } Tuple<u2> interfaces; /* interfaces[interfaces_count] */ u2 fields_count() { return fields.Length(); } Tuple<field_info> fields; /* fields[fields_count] */ u2 methods_count() { return methods.Length();} Tuple<method_info> methods; /* methods[methods_count] */ u2 attributes_count() { return attributes.Length(); } Tuple<attribute_info *> attributes; /* attributes[attributes_count] */ ClassFile(TypeSymbol *type_) : type(type_), constant_pool(8, 4), fields(6, 16), methods(6, 16) {} ~ClassFile() { for (int i = 1; i < constant_pool.Length(); i++) delete constant_pool[i]; for (int j = 0; j < attributes.Length(); j++) delete attributes[j]; return; } void Write() { Control &control = type -> semantic_environment -> sem -> control; if (! control.option.nowrite) { output_buffer.PutB4(magic); output_buffer.PutB2(minor_version); output_buffer.PutB2(major_version); output_buffer.PutB2(constant_pool.Length()); for (int i = 1; i < constant_pool.Length(); i++) { constant_pool[i] -> put(output_buffer); if (constant_pool[i] -> tag == CONSTANT_Long || constant_pool[i] -> tag == CONSTANT_Double) i++;; // skip the next entry for eight-byte constants } output_buffer.PutB2(access_flags); output_buffer.PutB2(this_class); output_buffer.PutB2(super_class); output_buffer.PutB2(interfaces.Length()); for (int j = 0; j < interfaces.Length(); j++) output_buffer.PutB2(interfaces[j]); output_buffer.PutB2(fields.Length()); for (int k = 0; k < fields.Length(); k++) fields[k].put(output_buffer); output_buffer.PutB2(methods.Length()); for (int l = 0; l < methods.Length(); l++) methods[l].put(output_buffer); output_buffer.PutB2(attributes.Length()); for (int m = 0; m < attributes.Length(); m++) attributes[m] -> put(output_buffer); char *class_file_name = type -> ClassName(); if (control.option.verbose) { cout << "[write "; Unicode::Cout(class_file_name); cout << "]\n"; } if (! output_buffer.WriteToFile(class_file_name)) { int length = strlen(class_file_name); wchar_t *name = new wchar_t[length + 1]; for (int i = 0; i < length; i++) name[i] = class_file_name[i]; name[length] = U_NULL; control.system_semantic -> ReportSemError(SemanticError::CANNOT_WRITE_FILE, 0, 0, name); delete [] name; } } return; } protected: TypeSymbol *type; OutputBuffer output_buffer; }; #endif