-
Notifications
You must be signed in to change notification settings - Fork 273
/
Copy pathjava_bytecode_parse_tree.h
365 lines (296 loc) · 9.58 KB
/
java_bytecode_parse_tree.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
/*******************************************************************\
Module:
Author: Daniel Kroening, [email protected]
\*******************************************************************/
#ifndef CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_PARSE_TREE_H
#define CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_PARSE_TREE_H
#include <util/std_types.h>
#include "bytecode_info.h"
#include "java_types.h"
#include <list>
#include <map>
#include <set>
typedef uint16_t method_offsett;
struct java_bytecode_parse_treet
{
// Disallow copy construction and copy assignment, but allow move construction
// and move assignment.
java_bytecode_parse_treet(const java_bytecode_parse_treet &) = delete;
java_bytecode_parse_treet &
operator=(const java_bytecode_parse_treet &) = delete;
java_bytecode_parse_treet(java_bytecode_parse_treet &&) = default;
java_bytecode_parse_treet &operator=(java_bytecode_parse_treet &&) = default;
struct annotationt
{
typet type;
struct element_value_pairt
{
irep_idt element_name;
exprt value;
void output(std::ostream &) const;
};
typedef std::vector<element_value_pairt> element_value_pairst;
element_value_pairst element_value_pairs;
void output(std::ostream &) const;
};
typedef std::vector<annotationt> annotationst;
static std::optional<annotationt> find_annotation(
const annotationst &annotations,
const irep_idt &annotation_type_name);
struct instructiont
{
source_locationt source_location;
method_offsett address;
u8 bytecode;
typedef std::vector<exprt> argst;
argst args;
};
struct membert
{
std::string descriptor;
std::optional<std::string> signature;
irep_idt name;
bool is_public, is_protected, is_private, is_static, is_final;
annotationst annotations;
membert():
is_public(false), is_protected(false),
is_private(false), is_static(false), is_final(false)
{
}
bool has_annotation(const irep_idt &annotation_id) const
{
return find_annotation(annotations, annotation_id).has_value();
}
};
struct methodt : public membert
{
irep_idt base_name;
bool is_native = false, is_abstract = false, is_synchronized = false,
is_bridge = false, is_varargs = false, is_synthetic = false;
source_locationt source_location;
typedef std::vector<instructiont> instructionst;
instructionst instructions;
instructiont &add_instruction()
{
instructions.push_back(instructiont());
return instructions.back();
}
/// Java annotations that were applied to parameters of this method
/// \remarks Each element in the vector corresponds to the annotations on
/// the parameter of this method with the matching index. A parameter that
/// does not have annotations can have an entry in this vector that is an
/// empty annotationst. Trailing parameters that have no annotations may be
/// entirely omitted from this vector.
std::vector<annotationst> parameter_annotations;
struct exceptiont
{
exceptiont()
: start_pc(0), end_pc(0), handler_pc(0), catch_type(irep_idt())
{
}
method_offsett start_pc;
method_offsett end_pc;
method_offsett handler_pc;
struct_tag_typet catch_type;
};
typedef std::vector<exceptiont> exception_tablet;
exception_tablet exception_table;
std::vector<irep_idt> throws_exception_table;
struct local_variablet
{
irep_idt name;
std::string descriptor;
std::optional<std::string> signature;
method_offsett index;
method_offsett start_pc;
method_offsett length;
};
typedef std::vector<local_variablet> local_variable_tablet;
local_variable_tablet local_variable_table;
struct verification_type_infot
{
enum verification_type_info_type { TOP, INTEGER, FLOAT, LONG, DOUBLE,
ITEM_NULL, UNINITIALIZED_THIS,
OBJECT, UNINITIALIZED};
verification_type_info_type type;
u1 tag;
u2 cpool_index;
u2 offset;
};
struct stack_map_table_entryt
{
enum stack_frame_type
{
SAME, SAME_LOCALS_ONE_STACK, SAME_LOCALS_ONE_STACK_EXTENDED,
CHOP, SAME_EXTENDED, APPEND, FULL
};
stack_frame_type type;
size_t offset_delta;
size_t chops;
size_t appends;
typedef std::vector<verification_type_infot>
local_verification_type_infot;
typedef std::vector<verification_type_infot>
stack_verification_type_infot;
local_verification_type_infot locals;
stack_verification_type_infot stack;
};
typedef std::vector<stack_map_table_entryt> stack_map_tablet;
stack_map_tablet stack_map_table;
void output(std::ostream &out) const;
methodt()
: is_native(false),
is_abstract(false),
is_synchronized(false),
is_bridge(false)
{
}
};
struct fieldt : public membert
{
bool is_enum;
void output(std::ostream &out) const;
fieldt() : is_enum(false)
{
}
};
struct classt
{
classt() = default;
/// Create a class \p name.
explicit classt(const irep_idt &name) : name(name)
{
}
// Disallow copy construction and copy assignment, but allow move
// construction and move assignment.
classt(const classt &) = delete;
classt &operator=(const classt &) = delete;
classt(classt &&) = default;
classt &operator=(classt &&) = default;
irep_idt name, super_class, inner_name;
bool is_abstract=false;
bool is_enum=false;
bool is_public=false, is_protected=false, is_private=false;
bool is_final = false;
bool is_interface = false;
bool is_synthetic = false;
bool is_annotation = false;
bool is_inner_class = false;
bool is_static_class = false;
bool is_anonymous_class = false;
bool attribute_bootstrapmethods_read = false;
irep_idt outer_class; // when no outer class is set, there is no outer class
size_t enum_elements=0;
typedef std::vector<u2> u2_valuest;
struct lambda_method_handlet
{
java_class_typet::method_handle_kindt handle_type;
std::optional<class_method_descriptor_exprt> method_descriptor;
/// Construct a lambda method handle with parameters \p params.
lambda_method_handlet(
const class_method_descriptor_exprt &method_descriptor,
java_class_typet::method_handle_kindt handle_type)
: handle_type(handle_type), method_descriptor(method_descriptor)
{
PRECONDITION(
handle_type != java_class_typet::method_handle_kindt::UNKNOWN_HANDLE);
}
lambda_method_handlet()
: handle_type(java_class_typet::method_handle_kindt::UNKNOWN_HANDLE),
method_descriptor()
{
}
static lambda_method_handlet get_unknown_handle()
{
return lambda_method_handlet{};
}
bool is_unknown_handle() const
{
return handle_type ==
java_class_typet::method_handle_kindt::UNKNOWN_HANDLE;
}
const class_method_descriptor_exprt &get_method_descriptor() const
{
PRECONDITION(!is_unknown_handle());
return *method_descriptor;
}
};
// TODO(tkiley): This map shouldn't be interacted with directly (instead
// TODO(tkiley): using add_method_handle and get_method_handle and instead
// TODO(tkiley): should be made private. TG-2785
typedef std::map<std::pair<irep_idt, size_t>, lambda_method_handlet>
lambda_method_handle_mapt;
lambda_method_handle_mapt lambda_method_handle_map;
typedef std::list<irep_idt> implementst;
implementst implements;
std::optional<std::string> signature;
typedef std::list<fieldt> fieldst;
typedef std::list<methodt> methodst;
fieldst fields;
methodst methods;
annotationst annotations;
fieldt &add_field()
{
fields.push_back(fieldt());
return fields.back();
}
methodt &add_method()
{
methods.push_back(methodt());
return methods.back();
}
void add_method_handle(
size_t bootstrap_index,
const lambda_method_handlet &handle)
{
lambda_method_handle_map[{name, bootstrap_index}] = handle;
}
const lambda_method_handlet &get_method_handle(size_t bootstrap_index) const
{
return lambda_method_handle_map.at({name, bootstrap_index});
}
void output(std::ostream &out) const;
};
classt parsed_class;
void output(std::ostream &out) const;
typedef std::set<irep_idt> class_refst;
class_refst class_refs;
bool loading_successful = false;
/// An empty bytecode parse tree, no class name set
java_bytecode_parse_treet() = default;
/// Create a blank parse tree for class \p class_name.
explicit java_bytecode_parse_treet(const irep_idt &class_name)
: parsed_class(class_name)
{
}
};
/// Represents the argument of an instruction that uses a CONSTANT_Fieldref
/// This is used for example as an argument to a getstatic and putstatic
/// instruction
class fieldref_exprt : public exprt
{
public:
fieldref_exprt(
const typet &type,
const irep_idt &component_name,
const irep_idt &class_name)
: exprt(ID_empty_string, type)
{
set(ID_class, class_name);
set(ID_component_name, component_name);
}
irep_idt class_name() const
{
return get(ID_class);
}
irep_idt component_name() const
{
return get(ID_component_name);
}
};
template <>
inline bool can_cast_expr<fieldref_exprt>(const exprt &base)
{
return !base.get(ID_class).empty() && !base.get(ID_component_name).empty();
}
#endif // CPROVER_JAVA_BYTECODE_JAVA_BYTECODE_PARSE_TREE_H