1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 #ifndef INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX
29 #define INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX
30 
31 #include "codemaker/unotype.hxx"
32 #include "sal/types.h"
33 
34 #include <list>
35 #include <map>
36 #include <utility>
37 #include <vector>
38 
39 class FileStream;
40 namespace rtl { class OString; }
41 
42 namespace codemaker { namespace javamaker {
43 
44 class ClassFile {
45 public:
46     enum AccessFlags {
47         ACC_PUBLIC = 0x0001,
48         ACC_PRIVATE = 0x0002,
49         ACC_STATIC = 0x0008,
50         ACC_FINAL = 0x0010,
51         ACC_SUPER = 0x0020,
52         ACC_VARARGS = 0x0080,
53         ACC_INTERFACE = 0x0200,
54         ACC_ABSTRACT = 0x0400,
55         ACC_SYNTHETIC = 0x1000
56     };
57 
58     class Code {
59     public:
60         typedef std::vector< unsigned char >::size_type Branch;
61         typedef std::vector< unsigned char >::size_type Position;
62 
63         ~Code();
64 
65         void instrAastore();
66 
67         void instrAconstNull();
68 
69         void instrAnewarray(rtl::OString const & type);
70 
71         void instrAreturn();
72 
73         void instrAthrow();
74 
75         void instrCheckcast(rtl::OString const & type);
76 
77         void instrDup();
78 
79         void instrGetstatic(
80             rtl::OString const & type, rtl::OString const & name,
81             rtl::OString const & descriptor);
82 
83         Branch instrIfAcmpne();
84 
85         Branch instrIfeq();
86 
87         Branch instrIfnull();
88 
89         void instrInstanceof(rtl::OString const & type);
90 
91         void instrInvokeinterface(
92             rtl::OString const & type, rtl::OString const & name,
93             rtl::OString const & descriptor, sal_uInt8 args);
94 
95         void instrInvokespecial(
96             rtl::OString const & type, rtl::OString const & name,
97             rtl::OString const & descriptor);
98 
99         void instrInvokestatic(
100             rtl::OString const & type, rtl::OString const & name,
101             rtl::OString const & descriptor);
102 
103         void instrInvokevirtual(
104             rtl::OString const & type, rtl::OString const & name,
105             rtl::OString const & descriptor);
106 
107         void instrLookupswitch(
108             Code const * defaultBlock,
109             std::list< std::pair< sal_Int32, Code * > > const & blocks);
110 
111         void instrNew(rtl::OString const & type);
112 
113         void instrNewarray(codemaker::UnoType::Sort sort);
114 
115         void instrPop();
116 
117         void instrPutfield(
118             rtl::OString const & type, rtl::OString const & name,
119             rtl::OString const & descriptor);
120 
121         void instrPutstatic(
122             rtl::OString const & type, rtl::OString const & name,
123             rtl::OString const & descriptor);
124 
125         void instrReturn();
126 
127         void instrSwap();
128 
129         void instrTableswitch(
130             Code const * defaultBlock, sal_Int32 low,
131             std::list< Code * > const & blocks);
132 
133         void loadIntegerConstant(sal_Int32 value);
134 
135         void loadStringConstant(rtl::OString const & value);
136 
137         void loadLocalInteger(sal_uInt16 index);
138 
139         void loadLocalLong(sal_uInt16 index);
140 
141         void loadLocalFloat(sal_uInt16 index);
142 
143         void loadLocalDouble(sal_uInt16 index);
144 
145         void loadLocalReference(sal_uInt16 index);
146 
147         void storeLocalReference(sal_uInt16 index);
148 
149         void branchHere(Branch branch);
150 
151         void addException(
152             Position start, Position end, Position handler,
153             rtl::OString const & type);
154 
155         void setMaxStackAndLocals(sal_uInt16 maxStack, sal_uInt16 maxLocals)
156         { m_maxStack = maxStack; m_maxLocals = maxLocals; }
157 
158         Position getPosition() const;
159 
160     private:
161         Code(Code &); // not implemented
162         void operator =(Code); // not implemented
163 
164         Code(ClassFile & classFile);
165 
166         void ldc(sal_uInt16 index);
167 
168         void accessLocal(
169             sal_uInt16 index, sal_uInt8 fastOp, sal_uInt8 normalOp);
170 
171         ClassFile & m_classFile;
172         sal_uInt16 m_maxStack;
173         sal_uInt16 m_maxLocals;
174         std::vector< unsigned char > m_code;
175         sal_uInt16 m_exceptionTableLength;
176         std::vector< unsigned char > m_exceptionTable;
177 
178         friend class ClassFile;
179     };
180 
181     ClassFile(
182         AccessFlags accessFlags, rtl::OString const & thisClass,
183         rtl::OString const & superClass, rtl::OString const & signature);
184 
185     ~ClassFile();
186 
187     Code * newCode();
188 
189     sal_uInt16 addIntegerInfo(sal_Int32 value);
190 
191     sal_uInt16 addFloatInfo(float value);
192 
193     sal_uInt16 addLongInfo(sal_Int64 value);
194 
195     sal_uInt16 addDoubleInfo(double value);
196 
197     void addInterface(rtl::OString const & interface);
198 
199     void addField(
200         AccessFlags accessFlags, rtl::OString const & name,
201         rtl::OString const & descriptor, sal_uInt16 constantValueIndex,
202         rtl::OString const & signature);
203 
204     void addMethod(
205         AccessFlags accessFlags, rtl::OString const & name,
206         rtl::OString const & descriptor, Code const * code,
207         std::vector< rtl::OString > const & exceptions,
208         rtl::OString const & signature);
209 
210     void write(FileStream & file) const; //TODO
211 
212 private:
213     typedef std::map< rtl::OString, sal_uInt16 > Map;
214 
215     ClassFile(ClassFile &); // not implemented
216     void operator =(ClassFile); // not implemented
217 
218     sal_uInt16 nextConstantPoolIndex(sal_uInt16 width);
219 
220     sal_uInt16 addUtf8Info(rtl::OString const & value);
221 
222     sal_uInt16 addClassInfo(rtl::OString const & type);
223 
224     sal_uInt16 addStringInfo(rtl::OString const & value);
225 
226     sal_uInt16 addFieldrefInfo(
227         rtl::OString const & type, rtl::OString const & name,
228         rtl::OString const & descriptor);
229 
230     sal_uInt16 addMethodrefInfo(
231         rtl::OString const & type, rtl::OString const & name,
232         rtl::OString const & descriptor);
233 
234     sal_uInt16 addInterfaceMethodrefInfo(
235         rtl::OString const & type, rtl::OString const & name,
236         rtl::OString const & descriptor);
237 
238     sal_uInt16 addNameAndTypeInfo(
239         rtl::OString const & name, rtl::OString const & descriptor);
240 
241     void appendSignatureAttribute(
242         std::vector< unsigned char > & stream, rtl::OString const & signature);
243 
244     sal_uInt16 m_constantPoolCount;
245     std::vector< unsigned char > m_constantPool;
246     std::map< rtl::OString, sal_uInt16 > m_utf8Infos;
247     std::map< sal_Int32, sal_uInt16 > m_integerInfos;
248     std::map< sal_Int64, sal_uInt16 > m_longInfos;
249     std::map< float, sal_uInt16 > m_floatInfos;
250     std::map< double, sal_uInt16 > m_doubleInfos;
251     std::map< sal_uInt16, sal_uInt16 > m_classInfos;
252     std::map< sal_uInt16, sal_uInt16 > m_stringInfos;
253     std::map< sal_uInt32, sal_uInt16 > m_fieldrefInfos;
254     std::map< sal_uInt32, sal_uInt16 > m_methodrefInfos;
255     std::map< sal_uInt32, sal_uInt16 > m_interfaceMethodrefInfos;
256     std::map< sal_uInt32, sal_uInt16 > m_nameAndTypeInfos;
257     AccessFlags m_accessFlags;
258     sal_uInt16 m_thisClass;
259     sal_uInt16 m_superClass;
260     sal_uInt16 m_interfacesCount;
261     std::vector< unsigned char > m_interfaces;
262     sal_uInt16 m_fieldsCount;
263     std::vector< unsigned char > m_fields;
264     sal_uInt16 m_methodsCount;
265     std::vector< unsigned char > m_methods;
266     sal_uInt16 m_attributesCount;
267     std::vector< unsigned char > m_attributes;
268 
269     friend class Code;
270 };
271 
272 } }
273 
274 #endif // INCLUDED_CODEMAKER_SOURCE_JAVAMAKER_CLASSFILE_HXX
275