summaryrefslogtreecommitdiffstats
path: root/libraries/pack200/src/bands.h
blob: 66c5aec40a28bcc5bc28d4204e5b9584f1b7b836 (plain)
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
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
/*
 * Copyright (c) 2002, 2005, Oracle and/or its affiliates. All rights reserved.
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
 * published by the Free Software Foundation.  Oracle designates this
 * particular file as subject to the "Classpath" exception as provided
 * by Oracle in the LICENSE file that accompanied this code.
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
 */

// -*- C++ -*-
struct entry;
struct cpindex;
struct unpacker;

struct band
{
    int bn;       // band_number of this band
    coding *defc; // default coding method
    cpindex *ix;  // CP entry mapping, if CPRefBand
    byte ixTag;   // 0 or 1; nullptr is coded as (nullOK?0:-1)
    byte nullOK;  // 0 or 1; nullptr is coded as (nullOK?0:-1)
    int length;   // expected # values
    unpacker *u;  // back pointer

    value_stream vs[2]; // source of values
    coding_method cm;   // method used for initial state of vs[0]
    byte *rplimit;      // end of band (encoded, transmitted)

    int total_memo; // cached value of getIntTotal, or -1
    int *hist0;     // approximate. histogram
    enum
    {
        HIST0_MIN = 0,
        HIST0_MAX = 255
    }; // catches the usual cases

    // properties for attribute layout elements:
    byte le_kind;   // EK_XXX
    byte le_bci;    // 0,EK_BCI,EK_BCD,EK_BCO
    byte le_back;   // ==EF_BACK
    byte le_len;    // 0,1,2,4 (size in classfile), or call addr
    band **le_body; // body of repl, union, call (nullptr-terminated)
// Note:  EK_CASE elements use hist0 to record union tags.
#define le_casetags hist0

    band &nextBand()
    {
        return this[1];
    }
    band &prevBand()
    {
        return this[-1];
    }

    void init(unpacker *u_, int bn_, coding *defc_)
    {
        u = u_;
        cm.u = u_;
        bn = bn_;
        defc = defc_;
    }
    void init(unpacker *u_, int bn_, int defcSpec)
    {
        init(u_, bn_, coding::findBySpec(defcSpec));
    }
    void initRef(int ixTag_ = 0, bool nullOK_ = false)
    {
        ixTag = ixTag_;
        nullOK = nullOK_;
        setIndexByTag(ixTag);
    }

    void expectMoreLength(int l)
    {
        assert(length >= 0);        // able to accept a length
        assert((int)l >= 0);        // no overflow
        assert(rplimit == nullptr); // readData not yet called
        length += l;
        assert(length >= l); // no overflow
    }

    void setIndex(cpindex *ix_);
    void setIndexByTag(byte tag);

    // Parse the band and its meta-coding header.
    void readData(int expectedLength = 0);

    // Reset the band for another pass (Cf. Java Band.resetForSecondPass.)
    void rewind()
    {
        cm.reset(&vs[0]);
    }

    byte *&curRP()
    {
        return vs[0].rp;
    }
    byte *minRP()
    {
        return cm.vs0.rp;
    }
    byte *maxRP()
    {
        return rplimit;
    }
    size_t size()
    {
        return maxRP() - minRP();
    }

    int getByte()
    {
        assert(ix == nullptr);
        return vs[0].getByte();
    }
    int getInt()
    {
        assert(ix == nullptr);
        return vs[0].getInt();
    }
    entry *getRefN()
    {
        assert(ix != nullptr);
        return getRefCommon(ix, true);
    }
    entry *getRef()
    {
        assert(ix != nullptr);
        return getRefCommon(ix, false);
    }
    entry *getRefUsing(cpindex *ix2)
    {
        assert(ix == nullptr);
        return getRefCommon(ix2, true);
    }
    entry *getRefCommon(cpindex *ix, bool nullOK);
    int64_t getLong(band &lo_band, bool have_hi);

    static int64_t makeLong(uint32_t hi, uint32_t lo)
    {
        return ((uint64_t)hi << 32) + (((uint64_t)lo << 32) >> 32);
    }

    int getIntTotal();
    int getIntCount(int tag);

    static band *makeBands(unpacker *u);
    static void initIndexes(unpacker *u);
};

extern band all_bands[];

#define BAND_LOCAL /*                                                                          \
  band* band_temp = all_bands;                                                                 \
  band* all_bands = band_temp */

// Band schema:
enum band_number
{
    // e_archive_magic,
    // e_archive_header,
    // e_band_headers,

    // constant pool contents
    e_cp_Utf8_prefix,
    e_cp_Utf8_suffix,
    e_cp_Utf8_chars,
    e_cp_Utf8_big_suffix,
    e_cp_Utf8_big_chars,
    e_cp_Int,
    e_cp_Float,
    e_cp_Long_hi,
    e_cp_Long_lo,
    e_cp_Double_hi,
    e_cp_Double_lo,
    e_cp_String,
    e_cp_Class,
    e_cp_Signature_form,
    e_cp_Signature_classes,
    e_cp_Descr_name,
    e_cp_Descr_type,
    e_cp_Field_class,
    e_cp_Field_desc,
    e_cp_Method_class,
    e_cp_Method_desc,
    e_cp_Imethod_class,
    e_cp_Imethod_desc,

    // bands which define transmission of attributes
    e_attr_definition_headers,
    e_attr_definition_name,
    e_attr_definition_layout,

    // band for hardwired InnerClasses attribute (shared across the package)
    e_ic_this_class,
    e_ic_flags,
    // These bands contain data only where flags sets ACC_IC_LONG_FORM:
    e_ic_outer_class,
    e_ic_name,

    // bands for carrying class schema information:
    e_class_this,
    e_class_super,
    e_class_interface_count,
    e_class_interface,

    // bands for class members
    e_class_field_count,
    e_class_method_count,
    e_field_descr,
    e_field_flags_hi,
    e_field_flags_lo,
    e_field_attr_count,
    e_field_attr_indexes,
    e_field_attr_calls,
    e_field_ConstantValue_KQ,
    e_field_Signature_RS,
    e_field_metadata_bands,
    e_field_attr_bands,
    e_method_descr,
    e_method_flags_hi,
    e_method_flags_lo,
    e_method_attr_count,
    e_method_attr_indexes,
    e_method_attr_calls,
    e_method_Exceptions_N,
    e_method_Exceptions_RC,
    e_method_Signature_RS,
    e_method_metadata_bands,
    e_method_attr_bands,
    e_class_flags_hi,
    e_class_flags_lo,
    e_class_attr_count,
    e_class_attr_indexes,
    e_class_attr_calls,
    e_class_SourceFile_RUN,
    e_class_EnclosingMethod_RC,
    e_class_EnclosingMethod_RDN,
    e_class_Signature_RS,
    e_class_metadata_bands,
    e_class_InnerClasses_N,
    e_class_InnerClasses_RC,
    e_class_InnerClasses_F,
    e_class_InnerClasses_outer_RCN,
    e_class_InnerClasses_name_RUN,
    e_class_ClassFile_version_minor_H,
    e_class_ClassFile_version_major_H,
    e_class_attr_bands,
    e_code_headers,
    e_code_max_stack,
    e_code_max_na_locals,
    e_code_handler_count,
    e_code_handler_start_P,
    e_code_handler_end_PO,
    e_code_handler_catch_PO,
    e_code_handler_class_RCN,

    // code attributes
    e_code_flags_hi,
    e_code_flags_lo,
    e_code_attr_count,
    e_code_attr_indexes,
    e_code_attr_calls,
    e_code_StackMapTable_N,
    e_code_StackMapTable_frame_T,
    e_code_StackMapTable_local_N,
    e_code_StackMapTable_stack_N,
    e_code_StackMapTable_offset,
    e_code_StackMapTable_T,
    e_code_StackMapTable_RC,
    e_code_StackMapTable_P,
    e_code_LineNumberTable_N,
    e_code_LineNumberTable_bci_P,
    e_code_LineNumberTable_line,
    e_code_LocalVariableTable_N,
    e_code_LocalVariableTable_bci_P,
    e_code_LocalVariableTable_span_O,
    e_code_LocalVariableTable_name_RU,
    e_code_LocalVariableTable_type_RS,
    e_code_LocalVariableTable_slot,
    e_code_LocalVariableTypeTable_N,
    e_code_LocalVariableTypeTable_bci_P,
    e_code_LocalVariableTypeTable_span_O,
    e_code_LocalVariableTypeTable_name_RU,
    e_code_LocalVariableTypeTable_type_RS,
    e_code_LocalVariableTypeTable_slot,
    e_code_attr_bands,

    // bands for bytecodes
    e_bc_codes,
    // remaining bands provide typed opcode fields required by the bc_codes
    e_bc_case_count,
    e_bc_case_value,
    e_bc_byte,
    e_bc_short,
    e_bc_local,
    e_bc_label,

    // ldc* operands:
    e_bc_intref,
    e_bc_floatref,
    e_bc_longref,
    e_bc_doubleref,
    e_bc_stringref,
    e_bc_classref,
    e_bc_fieldref,
    e_bc_methodref,
    e_bc_imethodref,

    // _self_linker_op family
    e_bc_thisfield,
    e_bc_superfield,
    e_bc_thismethod,
    e_bc_supermethod,

    // bc_invokeinit family:
    e_bc_initref,

    // bytecode escape sequences
    e_bc_escref,
    e_bc_escrefsize,
    e_bc_escsize,
    e_bc_escbyte,

    // file attributes and contents
    e_file_name,
    e_file_size_hi,
    e_file_size_lo,
    e_file_modtime,
    e_file_options,
    // e_file_bits,  // handled specially as an appendix
    BAND_LIMIT
};

// Symbolic names for bands, as if in a giant global struct:
//#define archive_magic all_bands[e_archive_magic]
//#define archive_header all_bands[e_archive_header]
//#define band_headers all_bands[e_band_headers]
#define cp_Utf8_prefix all_bands[e_cp_Utf8_prefix]
#define cp_Utf8_suffix all_bands[e_cp_Utf8_suffix]
#define cp_Utf8_chars all_bands[e_cp_Utf8_chars]
#define cp_Utf8_big_suffix all_bands[e_cp_Utf8_big_suffix]
#define cp_Utf8_big_chars all_bands[e_cp_Utf8_big_chars]
#define cp_Int all_bands[e_cp_Int]
#define cp_Float all_bands[e_cp_Float]
#define cp_Long_hi all_bands[e_cp_Long_hi]
#define cp_Long_lo all_bands[e_cp_Long_lo]
#define cp_Double_hi all_bands[e_cp_Double_hi]
#define cp_Double_lo all_bands[e_cp_Double_lo]
#define cp_String all_bands[e_cp_String]
#define cp_Class all_bands[e_cp_Class]
#define cp_Signature_form all_bands[e_cp_Signature_form]
#define cp_Signature_classes all_bands[e_cp_Signature_classes]
#define cp_Descr_name all_bands[e_cp_Descr_name]
#define cp_Descr_type all_bands[e_cp_Descr_type]
#define cp_Field_class all_bands[e_cp_Field_class]
#define cp_Field_desc all_bands[e_cp_Field_desc]
#define cp_Method_class all_bands[e_cp_Method_class]
#define cp_Method_desc all_bands[e_cp_Method_desc]
#define cp_Imethod_class all_bands[e_cp_Imethod_class]
#define cp_Imethod_desc all_bands[e_cp_Imethod_desc]
#define attr_definition_headers all_bands[e_attr_definition_headers]
#define attr_definition_name all_bands[e_attr_definition_name]
#define attr_definition_layout all_bands[e_attr_definition_layout]
#define ic_this_class all_bands[e_ic_this_class]
#define ic_flags all_bands[e_ic_flags]
#define ic_outer_class all_bands[e_ic_outer_class]
#define ic_name all_bands[e_ic_name]
#define class_this all_bands[e_class_this]
#define class_super all_bands[e_class_super]
#define class_interface_count all_bands[e_class_interface_count]
#define class_interface all_bands[e_class_interface]
#define class_field_count all_bands[e_class_field_count]
#define class_method_count all_bands[e_class_method_count]
#define field_descr all_bands[e_field_descr]
#define field_flags_hi all_bands[e_field_flags_hi]
#define field_flags_lo all_bands[e_field_flags_lo]
#define field_attr_count all_bands[e_field_attr_count]
#define field_attr_indexes all_bands[e_field_attr_indexes]
#define field_ConstantValue_KQ all_bands[e_field_ConstantValue_KQ]
#define field_Signature_RS all_bands[e_field_Signature_RS]
#define field_attr_bands all_bands[e_field_attr_bands]
#define method_descr all_bands[e_method_descr]
#define method_flags_hi all_bands[e_method_flags_hi]
#define method_flags_lo all_bands[e_method_flags_lo]
#define method_attr_count all_bands[e_method_attr_count]
#define method_attr_indexes all_bands[e_method_attr_indexes]
#define method_Exceptions_N all_bands[e_method_Exceptions_N]
#define method_Exceptions_RC all_bands[e_method_Exceptions_RC]
#define method_Signature_RS all_bands[e_method_Signature_RS]
#define method_attr_bands all_bands[e_method_attr_bands]
#define class_flags_hi all_bands[e_class_flags_hi]
#define class_flags_lo all_bands[e_class_flags_lo]
#define class_attr_count all_bands[e_class_attr_count]
#define class_attr_indexes all_bands[e_class_attr_indexes]
#define class_SourceFile_RUN all_bands[e_class_SourceFile_RUN]
#define class_EnclosingMethod_RC all_bands[e_class_EnclosingMethod_RC]
#define class_EnclosingMethod_RDN all_bands[e_class_EnclosingMethod_RDN]
#define class_Signature_RS all_bands[e_class_Signature_RS]
#define class_InnerClasses_N all_bands[e_class_InnerClasses_N]
#define class_InnerClasses_RC all_bands[e_class_InnerClasses_RC]
#define class_InnerClasses_F all_bands[e_class_InnerClasses_F]
#define class_InnerClasses_outer_RCN all_bands[e_class_InnerClasses_outer_RCN]
#define class_InnerClasses_name_RUN all_bands[e_class_InnerClasses_name_RUN]
#define class_ClassFile_version_minor_H all_bands[e_class_ClassFile_version_minor_H]
#define class_ClassFile_version_major_H all_bands[e_class_ClassFile_version_major_H]
#define class_attr_bands all_bands[e_class_attr_bands]
#define code_headers all_bands[e_code_headers]
#define code_max_stack all_bands[e_code_max_stack]
#define code_max_na_locals all_bands[e_code_max_na_locals]
#define code_handler_count all_bands[e_code_handler_count]
#define code_handler_start_P all_bands[e_code_handler_start_P]
#define code_handler_end_PO all_bands[e_code_handler_end_PO]
#define code_handler_catch_PO all_bands[e_code_handler_catch_PO]
#define code_handler_class_RCN all_bands[e_code_handler_class_RCN]
#define code_flags_hi all_bands[e_code_flags_hi]
#define code_flags_lo all_bands[e_code_flags_lo]
#define code_attr_count all_bands[e_code_attr_count]
#define code_attr_indexes all_bands[e_code_attr_indexes]
#define code_StackMapTable_N all_bands[e_code_StackMapTable_N]
#define code_StackMapTable_frame_T all_bands[e_code_StackMapTable_frame_T]
#define code_StackMapTable_local_N all_bands[e_code_StackMapTable_local_N]
#define code_StackMapTable_stack_N all_bands[e_code_StackMapTable_stack_N]
#define code_StackMapTable_offset all_bands[e_code_StackMapTable_offset]
#define code_StackMapTable_T all_bands[e_code_StackMapTable_T]
#define code_StackMapTable_RC all_bands[e_code_StackMapTable_RC]
#define code_StackMapTable_P all_bands[e_code_StackMapTable_P]
#define code_LineNumberTable_N all_bands[e_code_LineNumberTable_N]
#define code_LineNumberTable_bci_P all_bands[e_code_LineNumberTable_bci_P]
#define code_LineNumberTable_line all_bands[e_code_LineNumberTable_line]
#define code_LocalVariableTable_N all_bands[e_code_LocalVariableTable_N]
#define code_LocalVariableTable_bci_P all_bands[e_code_LocalVariableTable_bci_P]
#define code_LocalVariableTable_span_O all_bands[e_code_LocalVariableTable_span_O]
#define code_LocalVariableTable_name_RU all_bands[e_code_LocalVariableTable_name_RU]
#define code_LocalVariableTable_type_RS all_bands[e_code_LocalVariableTable_type_RS]
#define code_LocalVariableTable_slot all_bands[e_code_LocalVariableTable_slot]
#define code_LocalVariableTypeTable_N all_bands[e_code_LocalVariableTypeTable_N]
#define code_LocalVariableTypeTable_bci_P all_bands[e_code_LocalVariableTypeTable_bci_P]
#define code_LocalVariableTypeTable_span_O all_bands[e_code_LocalVariableTypeTable_span_O]
#define code_LocalVariableTypeTable_name_RU all_bands[e_code_LocalVariableTypeTable_name_RU]
#define code_LocalVariableTypeTable_type_RS all_bands[e_code_LocalVariableTypeTable_type_RS]
#define code_LocalVariableTypeTable_slot all_bands[e_code_LocalVariableTypeTable_slot]
#define code_attr_bands all_bands[e_code_attr_bands]
#define bc_codes all_bands[e_bc_codes]
#define bc_case_count all_bands[e_bc_case_count]
#define bc_case_value all_bands[e_bc_case_value]
#define bc_byte all_bands[e_bc_byte]
#define bc_short all_bands[e_bc_short]
#define bc_local all_bands[e_bc_local]
#define bc_label all_bands[e_bc_label]
#define bc_intref all_bands[e_bc_intref]
#define bc_floatref all_bands[e_bc_floatref]
#define bc_longref all_bands[e_bc_longref]
#define bc_doubleref all_bands[e_bc_doubleref]
#define bc_stringref all_bands[e_bc_stringref]
#define bc_classref all_bands[e_bc_classref]
#define bc_fieldref all_bands[e_bc_fieldref]
#define bc_methodref all_bands[e_bc_methodref]
#define bc_imethodref all_bands[e_bc_imethodref]
#define bc_thisfield all_bands[e_bc_thisfield]
#define bc_superfield all_bands[e_bc_superfield]
#define bc_thismethod all_bands[e_bc_thismethod]
#define bc_supermethod all_bands[e_bc_supermethod]
#define bc_initref all_bands[e_bc_initref]
#define bc_escref all_bands[e_bc_escref]
#define bc_escrefsize all_bands[e_bc_escrefsize]
#define bc_escsize all_bands[e_bc_escsize]
#define bc_escbyte all_bands[e_bc_escbyte]
#define file_name all_bands[e_file_name]
#define file_size_hi all_bands[e_file_size_hi]
#define file_size_lo all_bands[e_file_size_lo]
#define file_modtime all_bands[e_file_modtime]
#define file_options all_bands[e_file_options]