From b6d455a02bd338e9dc0faa09d4d8177ecd8d569a Mon Sep 17 00:00:00 2001 From: Petr Mrázek Date: Sun, 10 Apr 2016 15:53:05 +0200 Subject: NOISSUE reorganize and document libraries --- depends/pack200/src/bands.cpp | 423 ---- depends/pack200/src/bands.h | 489 ---- depends/pack200/src/bytes.cpp | 217 -- depends/pack200/src/bytes.h | 286 --- depends/pack200/src/coding.cpp | 1044 -------- depends/pack200/src/coding.h | 247 -- depends/pack200/src/constants.h | 442 ---- depends/pack200/src/defines.h | 65 - depends/pack200/src/unpack.cpp | 4793 ------------------------------------- depends/pack200/src/unpack.h | 547 ----- depends/pack200/src/unpack200.cpp | 162 -- depends/pack200/src/utils.cpp | 71 - depends/pack200/src/utils.h | 53 - depends/pack200/src/zip.cpp | 589 ----- depends/pack200/src/zip.h | 110 - 15 files changed, 9538 deletions(-) delete mode 100644 depends/pack200/src/bands.cpp delete mode 100644 depends/pack200/src/bands.h delete mode 100644 depends/pack200/src/bytes.cpp delete mode 100644 depends/pack200/src/bytes.h delete mode 100644 depends/pack200/src/coding.cpp delete mode 100644 depends/pack200/src/coding.h delete mode 100644 depends/pack200/src/constants.h delete mode 100644 depends/pack200/src/defines.h delete mode 100644 depends/pack200/src/unpack.cpp delete mode 100644 depends/pack200/src/unpack.h delete mode 100644 depends/pack200/src/unpack200.cpp delete mode 100644 depends/pack200/src/utils.cpp delete mode 100644 depends/pack200/src/utils.h delete mode 100644 depends/pack200/src/zip.cpp delete mode 100644 depends/pack200/src/zip.h (limited to 'depends/pack200/src') diff --git a/depends/pack200/src/bands.cpp b/depends/pack200/src/bands.cpp deleted file mode 100644 index 1608d838..00000000 --- a/depends/pack200/src/bands.cpp +++ /dev/null @@ -1,423 +0,0 @@ -/* - * Copyright (c) 2002, 2009, 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++ -*- -// Small program for unpacking specially compressed Java packages. -// John R. Rose - -#include - -#include -#include -#include -#include -#include -#include - -#include "defines.h" -#include "bytes.h" -#include "utils.h" -#include "coding.h" -#include "bands.h" - -#include "constants.h" -#include "unpack.h" - -void band::readData(int expectedLength) -{ - assert(expectedLength >= 0); - assert(vs[0].cmk == cmk_ERROR); - if (expectedLength != 0) - { - assert(length == 0); - length = expectedLength; - } - if (length == 0) - { - assert((rplimit = cm.vs0.rp = u->rp) != nullptr); - return; - } - assert(length > 0); - - bool is_BYTE1 = (defc->spec == BYTE1_spec); - - if (is_BYTE1) - { - // No possibility of coding change. Sizing is exact. - u->ensure_input(length); - } - else - { - // Make a conservatively generous estimate of band size in bytes. - // Assume B == 5 everywhere. - // Assume awkward pop with all {U} values (2*5 per value) - int64_t generous = (int64_t)length * (B_MAX * 3 + 1) + C_SLOP; - u->ensure_input(generous); - } - - // Read one value to see what it might be. - int XB = _meta_default; - if (!is_BYTE1) - { - // must be a variable-length coding - assert(defc->B() > 1 && defc->L() > 0); - - value_stream xvs; - coding *valc = defc; - if (valc->D() != 0) - { - valc = coding::findBySpec(defc->B(), defc->H(), defc->S()); - assert(!valc->isMalloc); - } - xvs.init(u->rp, u->rplimit, valc); - int X = xvs.getInt(); - if (valc->S() != 0) - { - assert(valc->min <= -256); - XB = -1 - X; - } - else - { - int L = valc->L(); - assert(valc->max >= L + 255); - XB = X - L; - } - if (0 <= XB && XB < 256) - { - // Skip over the escape value. - u->rp = xvs.rp; - } - else - { - // No, it's still default. - XB = _meta_default; - } - } - - if (XB <= _meta_canon_max) - { - byte XB_byte = (byte)XB; - byte *XB_ptr = &XB_byte; - cm.init(u->rp, u->rplimit, XB_ptr, 0, defc, length, nullptr); - } - else - { - assert(u->meta_rp != nullptr); - // Scribble the initial byte onto the band. - byte *save_meta_rp = --u->meta_rp; - byte save_meta_xb = (*save_meta_rp); - (*save_meta_rp) = (byte)XB; - cm.init(u->rp, u->rplimit, u->meta_rp, 0, defc, length, nullptr); - (*save_meta_rp) = save_meta_xb; // put it back, just to be tidy - } - rplimit = u->rp; - - rewind(); -} - -void band::setIndex(cpindex *ix_) -{ - assert(ix_ == nullptr || ixTag == ix_->ixTag); - ix = ix_; -} -void band::setIndexByTag(byte tag) -{ - setIndex(u->cp.getIndex(tag)); -} - -entry *band::getRefCommon(cpindex *ix_, bool nullOKwithCaller) -{ - assert(ix_->ixTag == ixTag || - (ixTag == CONSTANT_Literal && ix_->ixTag >= CONSTANT_Integer && - ix_->ixTag <= CONSTANT_String)); - int n = vs[0].getInt() - nullOK; - // Note: band-local nullOK means nullptr encodes as 0. - // But nullOKwithCaller means caller is willing to tolerate a nullptr. - entry *ref = ix_->get(n); - if (ref == nullptr && !(nullOKwithCaller && n == -1)) - unpack_abort(n == -1 ? "nullptr ref" : "bad ref"); - return ref; -} - -int64_t band::getLong(band &lo_band, bool have_hi) -{ - band &hi_band = (*this); - assert(lo_band.bn == hi_band.bn + 1); - uint32_t lo = lo_band.getInt(); - if (!have_hi) - { - assert(hi_band.length == 0); - return makeLong(0, lo); - } - uint32_t hi = hi_band.getInt(); - return makeLong(hi, lo); -} - -int band::getIntTotal() -{ - if (length == 0) - return 0; - if (total_memo > 0) - return total_memo - 1; - int total = getInt(); - // overflow checks require that none of the addends are <0, - // and that the partial sums never overflow (wrap negative) - if (total < 0) - { - unpack_abort("overflow detected"); - } - for (int k = length - 1; k > 0; k--) - { - int prev_total = total; - total += vs[0].getInt(); - if (total < prev_total) - { - unpack_abort("overflow detected"); - } - } - rewind(); - total_memo = total + 1; - return total; -} - -int band::getIntCount(int tag) -{ - if (length == 0) - return 0; - if (tag >= HIST0_MIN && tag <= HIST0_MAX) - { - if (hist0 == nullptr) - { - // Lazily calculate an approximate histogram. - hist0 = U_NEW(int, (HIST0_MAX - HIST0_MIN) + 1); - for (int k = length; k > 0; k--) - { - int x = vs[0].getInt(); - if (x >= HIST0_MIN && x <= HIST0_MAX) - hist0[x - HIST0_MIN] += 1; - } - rewind(); - } - return hist0[tag - HIST0_MIN]; - } - int total = 0; - for (int k = length; k > 0; k--) - { - total += (vs[0].getInt() == tag) ? 1 : 0; - } - rewind(); - return total; -} - -#define INDEX_INIT(tag, nullOK, subindex) ((tag) + (subindex) * SUBINDEX_BIT + (nullOK) * 256) - -#define INDEX(tag) INDEX_INIT(tag, 0, 0) -#define NULL_OR_INDEX(tag) INDEX_INIT(tag, 1, 0) -#define SUB_INDEX(tag) INDEX_INIT(tag, 0, 1) -#define NO_INDEX 0 - -struct band_init -{ - int defc; - int index; -}; - -#define BAND_INIT(name, cspec, ix) \ - { \ - cspec, ix \ - } - -const band_init all_band_inits[] = - { - // BAND_INIT(archive_magic, BYTE1_spec, 0), - // BAND_INIT(archive_header, UNSIGNED5_spec, 0), - // BAND_INIT(band_headers, BYTE1_spec, 0), - BAND_INIT(cp_Utf8_prefix, DELTA5_spec, 0), BAND_INIT(cp_Utf8_suffix, UNSIGNED5_spec, 0), - BAND_INIT(cp_Utf8_chars, CHAR3_spec, 0), BAND_INIT(cp_Utf8_big_suffix, DELTA5_spec, 0), - BAND_INIT(cp_Utf8_big_chars, DELTA5_spec, 0), BAND_INIT(cp_Int, UDELTA5_spec, 0), - BAND_INIT(cp_Float, UDELTA5_spec, 0), BAND_INIT(cp_Long_hi, UDELTA5_spec, 0), - BAND_INIT(cp_Long_lo, DELTA5_spec, 0), BAND_INIT(cp_Double_hi, UDELTA5_spec, 0), - BAND_INIT(cp_Double_lo, DELTA5_spec, 0), - BAND_INIT(cp_String, UDELTA5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(cp_Class, UDELTA5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(cp_Signature_form, DELTA5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(cp_Signature_classes, UDELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(cp_Descr_name, DELTA5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(cp_Descr_type, UDELTA5_spec, INDEX(CONSTANT_Signature)), - BAND_INIT(cp_Field_class, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(cp_Field_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), - BAND_INIT(cp_Method_class, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(cp_Method_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), - BAND_INIT(cp_Imethod_class, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(cp_Imethod_desc, UDELTA5_spec, INDEX(CONSTANT_NameandType)), - BAND_INIT(attr_definition_headers, BYTE1_spec, 0), - BAND_INIT(attr_definition_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(attr_definition_layout, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(ic_this_class, UDELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(ic_flags, UNSIGNED5_spec, 0), - BAND_INIT(ic_outer_class, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Class)), - BAND_INIT(ic_name, DELTA5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), - BAND_INIT(class_this, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(class_super, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(class_interface_count, DELTA5_spec, 0), - BAND_INIT(class_interface, DELTA5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(class_field_count, DELTA5_spec, 0), - BAND_INIT(class_method_count, DELTA5_spec, 0), - BAND_INIT(field_descr, DELTA5_spec, INDEX(CONSTANT_NameandType)), - BAND_INIT(field_flags_hi, UNSIGNED5_spec, 0), - BAND_INIT(field_flags_lo, UNSIGNED5_spec, 0), - BAND_INIT(field_attr_count, UNSIGNED5_spec, 0), - BAND_INIT(field_attr_indexes, UNSIGNED5_spec, 0), - BAND_INIT(field_attr_calls, UNSIGNED5_spec, 0), - BAND_INIT(field_ConstantValue_KQ, UNSIGNED5_spec, INDEX(CONSTANT_Literal)), - BAND_INIT(field_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), - BAND_INIT(field_metadata_bands, -1, -1), BAND_INIT(field_attr_bands, -1, -1), - BAND_INIT(method_descr, MDELTA5_spec, INDEX(CONSTANT_NameandType)), - BAND_INIT(method_flags_hi, UNSIGNED5_spec, 0), - BAND_INIT(method_flags_lo, UNSIGNED5_spec, 0), - BAND_INIT(method_attr_count, UNSIGNED5_spec, 0), - BAND_INIT(method_attr_indexes, UNSIGNED5_spec, 0), - BAND_INIT(method_attr_calls, UNSIGNED5_spec, 0), - BAND_INIT(method_Exceptions_N, UNSIGNED5_spec, 0), - BAND_INIT(method_Exceptions_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(method_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), - BAND_INIT(method_metadata_bands, -1, -1), BAND_INIT(method_attr_bands, -1, -1), - BAND_INIT(class_flags_hi, UNSIGNED5_spec, 0), - BAND_INIT(class_flags_lo, UNSIGNED5_spec, 0), - BAND_INIT(class_attr_count, UNSIGNED5_spec, 0), - BAND_INIT(class_attr_indexes, UNSIGNED5_spec, 0), - BAND_INIT(class_attr_calls, UNSIGNED5_spec, 0), - BAND_INIT(class_SourceFile_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), - BAND_INIT(class_EnclosingMethod_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(class_EnclosingMethod_RDN, UNSIGNED5_spec, - NULL_OR_INDEX(CONSTANT_NameandType)), - BAND_INIT(class_Signature_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), - BAND_INIT(class_metadata_bands, -1, -1), - BAND_INIT(class_InnerClasses_N, UNSIGNED5_spec, 0), - BAND_INIT(class_InnerClasses_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(class_InnerClasses_F, UNSIGNED5_spec, 0), - BAND_INIT(class_InnerClasses_outer_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), - BAND_INIT(class_InnerClasses_name_RUN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Utf8)), - BAND_INIT(class_ClassFile_version_minor_H, UNSIGNED5_spec, 0), - BAND_INIT(class_ClassFile_version_major_H, UNSIGNED5_spec, 0), - BAND_INIT(class_attr_bands, -1, -1), BAND_INIT(code_headers, BYTE1_spec, 0), - BAND_INIT(code_max_stack, UNSIGNED5_spec, 0), - BAND_INIT(code_max_na_locals, UNSIGNED5_spec, 0), - BAND_INIT(code_handler_count, UNSIGNED5_spec, 0), - BAND_INIT(code_handler_start_P, BCI5_spec, 0), - BAND_INIT(code_handler_end_PO, BRANCH5_spec, 0), - BAND_INIT(code_handler_catch_PO, BRANCH5_spec, 0), - BAND_INIT(code_handler_class_RCN, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), - BAND_INIT(code_flags_hi, UNSIGNED5_spec, 0), - BAND_INIT(code_flags_lo, UNSIGNED5_spec, 0), - BAND_INIT(code_attr_count, UNSIGNED5_spec, 0), - BAND_INIT(code_attr_indexes, UNSIGNED5_spec, 0), - BAND_INIT(code_attr_calls, UNSIGNED5_spec, 0), - BAND_INIT(code_StackMapTable_N, UNSIGNED5_spec, 0), - BAND_INIT(code_StackMapTable_frame_T, BYTE1_spec, 0), - BAND_INIT(code_StackMapTable_local_N, UNSIGNED5_spec, 0), - BAND_INIT(code_StackMapTable_stack_N, UNSIGNED5_spec, 0), - BAND_INIT(code_StackMapTable_offset, UNSIGNED5_spec, 0), - BAND_INIT(code_StackMapTable_T, BYTE1_spec, 0), - BAND_INIT(code_StackMapTable_RC, UNSIGNED5_spec, INDEX(CONSTANT_Class)), - BAND_INIT(code_StackMapTable_P, BCI5_spec, 0), - BAND_INIT(code_LineNumberTable_N, UNSIGNED5_spec, 0), - BAND_INIT(code_LineNumberTable_bci_P, BCI5_spec, 0), - BAND_INIT(code_LineNumberTable_line, UNSIGNED5_spec, 0), - BAND_INIT(code_LocalVariableTable_N, UNSIGNED5_spec, 0), - BAND_INIT(code_LocalVariableTable_bci_P, BCI5_spec, 0), - BAND_INIT(code_LocalVariableTable_span_O, BRANCH5_spec, 0), - BAND_INIT(code_LocalVariableTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(code_LocalVariableTable_type_RS, UNSIGNED5_spec, INDEX(CONSTANT_Signature)), - BAND_INIT(code_LocalVariableTable_slot, UNSIGNED5_spec, 0), - BAND_INIT(code_LocalVariableTypeTable_N, UNSIGNED5_spec, 0), - BAND_INIT(code_LocalVariableTypeTable_bci_P, BCI5_spec, 0), - BAND_INIT(code_LocalVariableTypeTable_span_O, BRANCH5_spec, 0), - BAND_INIT(code_LocalVariableTypeTable_name_RU, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(code_LocalVariableTypeTable_type_RS, UNSIGNED5_spec, - INDEX(CONSTANT_Signature)), - BAND_INIT(code_LocalVariableTypeTable_slot, UNSIGNED5_spec, 0), - BAND_INIT(code_attr_bands, -1, -1), BAND_INIT(bc_codes, BYTE1_spec, 0), - BAND_INIT(bc_case_count, UNSIGNED5_spec, 0), BAND_INIT(bc_case_value, DELTA5_spec, 0), - BAND_INIT(bc_byte, BYTE1_spec, 0), BAND_INIT(bc_short, DELTA5_spec, 0), - BAND_INIT(bc_local, UNSIGNED5_spec, 0), BAND_INIT(bc_label, BRANCH5_spec, 0), - BAND_INIT(bc_intref, DELTA5_spec, INDEX(CONSTANT_Integer)), - BAND_INIT(bc_floatref, DELTA5_spec, INDEX(CONSTANT_Float)), - BAND_INIT(bc_longref, DELTA5_spec, INDEX(CONSTANT_Long)), - BAND_INIT(bc_doubleref, DELTA5_spec, INDEX(CONSTANT_Double)), - BAND_INIT(bc_stringref, DELTA5_spec, INDEX(CONSTANT_String)), - BAND_INIT(bc_classref, UNSIGNED5_spec, NULL_OR_INDEX(CONSTANT_Class)), - BAND_INIT(bc_fieldref, DELTA5_spec, INDEX(CONSTANT_Fieldref)), - BAND_INIT(bc_methodref, UNSIGNED5_spec, INDEX(CONSTANT_Methodref)), - BAND_INIT(bc_imethodref, DELTA5_spec, INDEX(CONSTANT_InterfaceMethodref)), - BAND_INIT(bc_thisfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), - BAND_INIT(bc_superfield, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Fieldref)), - BAND_INIT(bc_thismethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), - BAND_INIT(bc_supermethod, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), - BAND_INIT(bc_initref, UNSIGNED5_spec, SUB_INDEX(CONSTANT_Methodref)), - BAND_INIT(bc_escref, UNSIGNED5_spec, INDEX(CONSTANT_All)), - BAND_INIT(bc_escrefsize, UNSIGNED5_spec, 0), BAND_INIT(bc_escsize, UNSIGNED5_spec, 0), - BAND_INIT(bc_escbyte, BYTE1_spec, 0), - BAND_INIT(file_name, UNSIGNED5_spec, INDEX(CONSTANT_Utf8)), - BAND_INIT(file_size_hi, UNSIGNED5_spec, 0), BAND_INIT(file_size_lo, UNSIGNED5_spec, 0), - BAND_INIT(file_modtime, DELTA5_spec, 0), BAND_INIT(file_options, UNSIGNED5_spec, 0), - // BAND_INIT(file_bits, BYTE1_spec, 0), - {0, 0}}; - -band *band::makeBands(unpacker *u) -{ - band *tmp_all_bands = U_NEW(band, BAND_LIMIT); - for (int i = 0; i < BAND_LIMIT; i++) - { - assert((byte *)&all_band_inits[i + 1] < - (byte *)all_band_inits + sizeof(all_band_inits)); - const band_init &bi = all_band_inits[i]; - band &b = tmp_all_bands[i]; - coding *defc = coding::findBySpec(bi.defc); - assert((defc == nullptr) == (bi.defc == -1)); // no garbage, please - assert(defc == nullptr || !defc->isMalloc); - b.init(u, i, defc); - if (bi.index > 0) - { - b.nullOK = ((bi.index >> 8) & 1); - b.ixTag = (bi.index & 0xFF); - } - } - return tmp_all_bands; -} - -void band::initIndexes(unpacker *u) -{ - band *tmp_all_bands = u->all_bands; - for (int i = 0; i < BAND_LIMIT; i++) - { - band *scan = &tmp_all_bands[i]; - uint32_t tag = scan->ixTag; // Cf. #define INDEX(tag) above - if (tag != 0 && tag != CONSTANT_Literal && (tag & SUBINDEX_BIT) == 0) - { - scan->setIndex(u->cp.getIndex(tag)); - } - } -} diff --git a/depends/pack200/src/bands.h b/depends/pack200/src/bands.h deleted file mode 100644 index a56cd7d5..00000000 --- a/depends/pack200/src/bands.h +++ /dev/null @@ -1,489 +0,0 @@ -/* - * 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] diff --git a/depends/pack200/src/bytes.cpp b/depends/pack200/src/bytes.cpp deleted file mode 100644 index d3808afa..00000000 --- a/depends/pack200/src/bytes.cpp +++ /dev/null @@ -1,217 +0,0 @@ -/* - * Copyright (c) 2001, 2010, 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. - */ - -#include -#include -#include -#include -#include -#include "defines.h" -#include "bytes.h" -#include "utils.h" - -static byte dummy[1 << 10]; - -bool bytes::inBounds(const void *p) -{ - return p >= ptr && p < limit(); -} - -void bytes::malloc(size_t len_) -{ - len = len_; - ptr = NEW(byte, add_size(len_, 1)); // add trailing zero byte always - if (ptr == nullptr) - { - // set ptr to some victim memory, to ease escape - set(dummy, sizeof(dummy) - 1); - unpack_abort(ERROR_ENOMEM); - } -} - -void bytes::realloc(size_t len_) -{ - if (len == len_) - return; // nothing to do - if (ptr == dummy) - return; // escaping from an error - if (ptr == nullptr) - { - malloc(len_); - return; - } - byte *oldptr = ptr; - ptr = (len_ >= PSIZE_MAX) ? nullptr : (byte *)::realloc(ptr, add_size(len_, 1)); - if (ptr != nullptr) - { - if (len < len_) - memset(ptr + len, 0, len_ - len); - ptr[len_] = 0; - len = len_; - } - else - { - ptr = oldptr; // ease our escape - unpack_abort(ERROR_ENOMEM); - } -} - -void bytes::free() -{ - if (ptr == dummy) - return; // escaping from an error - if (ptr != nullptr) - { - ::free(ptr); - } - len = 0; - ptr = 0; -} - -int bytes::indexOf(byte c) -{ - byte *p = (byte *)memchr(ptr, c, len); - return (p == 0) ? -1 : (int)(p - ptr); -} - -byte *bytes::writeTo(byte *bp) -{ - memcpy(bp, ptr, len); - return bp + len; -} - -int bytes::compareTo(bytes &other) -{ - size_t l1 = len; - size_t l2 = other.len; - int cmp = memcmp(ptr, other.ptr, (l1 < l2) ? l1 : l2); - if (cmp != 0) - return cmp; - return (l1 < l2) ? -1 : (l1 > l2) ? 1 : 0; -} - -void bytes::saveFrom(const void *ptr_, size_t len_) -{ - malloc(len_); - // Save as much as possible. - if (len_ > len) - { - assert(ptr == dummy); // error recovery - len_ = len; - } - copyFrom(ptr_, len_); -} - -//#TODO: Need to fix for exception handling -void bytes::copyFrom(const void *ptr_, size_t len_, size_t offset) -{ - assert(len_ == 0 || inBounds(ptr + offset)); - assert(len_ == 0 || inBounds(ptr + offset + len_ - 1)); - memcpy(ptr + offset, ptr_, len_); -} - -// Make sure there are 'o' bytes beyond the fill pointer, -// advance the fill pointer, and return the old fill pointer. -byte *fillbytes::grow(size_t s) -{ - size_t nlen = add_size(b.len, s); - if (nlen <= allocated) - { - b.len = nlen; - return limit() - s; - } - size_t maxlen = nlen; - if (maxlen < 128) - maxlen = 128; - if (maxlen < allocated * 2) - maxlen = allocated * 2; - if (allocated == 0) - { - // Initial buffer was not malloced. Do not reallocate it. - bytes old = b; - b.malloc(maxlen); - if (b.len == maxlen) - old.writeTo(b.ptr); - } - else - { - b.realloc(maxlen); - } - allocated = b.len; - if (allocated != maxlen) - { - b.len = nlen - s; // back up - return dummy; // scribble during error recov. - } - // after realloc, recompute pointers - b.len = nlen; - assert(b.len <= allocated); - return limit() - s; -} - -void fillbytes::ensureSize(size_t s) -{ - if (allocated >= s) - return; - size_t len0 = b.len; - grow(s - size()); - b.len = len0; // put it back -} - -int ptrlist::indexOf(const void *x) -{ - int len = length(); - for (int i = 0; i < len; i++) - { - if (get(i) == x) - return i; - } - return -1; -} - -void ptrlist::freeAll() -{ - int len = length(); - for (int i = 0; i < len; i++) - { - void *p = (void *)get(i); - if (p != nullptr) - { - ::free(p); - } - } - free(); -} - -int intlist::indexOf(int x) -{ - int len = length(); - for (int i = 0; i < len; i++) - { - if (get(i) == x) - return i; - } - return -1; -} diff --git a/depends/pack200/src/bytes.h b/depends/pack200/src/bytes.h deleted file mode 100644 index b116efda..00000000 --- a/depends/pack200/src/bytes.h +++ /dev/null @@ -1,286 +0,0 @@ -/* - * Copyright (c) 2001, 2008, 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. - */ - -#pragma once - -struct bytes -{ - int8_t *ptr; - size_t len; - int8_t *limit() - { - return ptr + len; - } - - void set(int8_t *ptr_, size_t len_) - { - ptr = ptr_; - len = len_; - } - void set(const char *str) - { - ptr = (int8_t *)str; - len = strlen(str); - } - bool inBounds(const void *p); // p in [ptr, limit) - void malloc(size_t len_); - void realloc(size_t len_); - void free(); - void copyFrom(const void *ptr_, size_t len_, size_t offset = 0); - void saveFrom(const void *ptr_, size_t len_); - void saveFrom(const char *str) - { - saveFrom(str, strlen(str)); - } - void copyFrom(bytes &other, size_t offset = 0) - { - copyFrom(other.ptr, other.len, offset); - } - void saveFrom(bytes &other) - { - saveFrom(other.ptr, other.len); - } - void clear(int fill_byte = 0) - { - memset(ptr, fill_byte, len); - } - int8_t *writeTo(int8_t *bp); - bool equals(bytes &other) - { - return 0 == compareTo(other); - } - int compareTo(bytes &other); - bool contains(int8_t c) - { - return indexOf(c) >= 0; - } - int indexOf(int8_t c); - // substrings: - static bytes of(int8_t *ptr, size_t len) - { - bytes res; - res.set(ptr, len); - return res; - } - bytes slice(size_t beg, size_t end) - { - bytes res; - res.ptr = ptr + beg; - res.len = end - beg; - assert(res.len == 0 ||(inBounds(res.ptr) && inBounds(res.limit() - 1))); - return res; - } - // building C strings inside byte buffers: - bytes &strcat(const char *str) - { - ::strcat((char *)ptr, str); - return *this; - } - bytes &strcat(bytes &other) - { - ::strncat((char *)ptr, (char *)other.ptr, other.len); - return *this; - } - char *strval() - { - assert(strlen((char *)ptr) == len); - return (char *)ptr; - } -}; -#define BYTES_OF(var) (bytes::of((int8_t *)&(var), sizeof(var))) - -struct fillbytes -{ - bytes b; - size_t allocated; - - int8_t *base() - { - return b.ptr; - } - size_t size() - { - return b.len; - } - int8_t *limit() - { - return b.limit(); - } // logical limit - void setLimit(int8_t *lp) - { - assert(isAllocated(lp)); - b.len = lp - b.ptr; - } - int8_t *end() - { - return b.ptr + allocated; - } // physical limit - int8_t *loc(size_t o) - { - assert(o < b.len); - return b.ptr + o; - } - void init() - { - allocated = 0; - b.set(nullptr, 0); - } - void init(size_t s) - { - init(); - ensureSize(s); - } - void free() - { - if (allocated != 0) - b.free(); - allocated = 0; - } - void empty() - { - b.len = 0; - } - int8_t *grow(size_t s); // grow so that limit() += s - int getByte(uint32_t i) - { - return *loc(i) & 0xFF; - } - void addByte(int8_t x) - { - *grow(1) = x; - } - void ensureSize(size_t s); // make sure allocated >= s - void trimToSize() - { - if (allocated > size()) - b.realloc(allocated = size()); - } - bool canAppend(size_t s) - { - return allocated > b.len + s; - } - bool isAllocated(int8_t *p) - { - return p >= base() && p <= end(); - } // asserts - void set(bytes &src) - { - set(src.ptr, src.len); - } - - void set(int8_t *ptr, size_t len) - { - b.set(ptr, len); - allocated = 0; // mark as not reallocatable - } - - // block operations on resizing byte buffer: - fillbytes &append(const void *ptr_, size_t len_) - { - memcpy(grow(len_), ptr_, len_); - return (*this); - } - fillbytes &append(bytes &other) - { - return append(other.ptr, other.len); - } - fillbytes &append(const char *str) - { - return append(str, strlen(str)); - } -}; - -struct ptrlist : fillbytes -{ - typedef const void *cvptr; - int length() - { - return (int)(size() / sizeof(cvptr)); - } - cvptr *base() - { - return (cvptr *)fillbytes::base(); - } - cvptr &get(int i) - { - return *(cvptr *)loc(i * sizeof(cvptr)); - } - cvptr *limit() - { - return (cvptr *)fillbytes::limit(); - } - void add(cvptr x) - { - *(cvptr *)grow(sizeof(x)) = x; - } - void popTo(int l) - { - assert(l <= length()); - b.len = l * sizeof(cvptr); - } - int indexOf(cvptr x); - bool contains(cvptr x) - { - return indexOf(x) >= 0; - } - void freeAll(); // frees every ptr on the list, plus the list itself -}; -// Use a macro rather than mess with subtle mismatches -// between member and non-member function pointers. -#define PTRLIST_QSORT(ptrls, fn) ::qsort((ptrls).base(), (ptrls).length(), sizeof(void *), fn) - -struct intlist : fillbytes -{ - int length() - { - return (int)(size() / sizeof(int)); - } - int *base() - { - return (int *)fillbytes::base(); - } - int &get(int i) - { - return *(int *)loc(i * sizeof(int)); - } - int *limit() - { - return (int *)fillbytes::limit(); - } - void add(int x) - { - *(int *)grow(sizeof(x)) = x; - } - void popTo(int l) - { - assert(l <= length()); - b.len = l * sizeof(int); - } - int indexOf(int x); - bool contains(int x) - { - return indexOf(x) >= 0; - } -}; diff --git a/depends/pack200/src/coding.cpp b/depends/pack200/src/coding.cpp deleted file mode 100644 index 6bd17a3c..00000000 --- a/depends/pack200/src/coding.cpp +++ /dev/null @@ -1,1044 +0,0 @@ -/* - * Copyright (c) 2002, 2009, 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++ -*- -// Small program for unpacking specially compressed Java packages. -// John R. Rose - -#include -#include -#include -#include -#include -#include - -#include "defines.h" -#include "bytes.h" -#include "utils.h" -#include "coding.h" - -#include "constants.h" -#include "unpack.h" - -extern coding basic_codings[]; - -// CODING_PRIVATE causes a lot of them -#pragma GCC diagnostic ignored "-Wunused-variable" - -#define CODING_PRIVATE(spec) \ - int spec_ = spec; \ - int B = CODING_B(spec_); \ - int H = CODING_H(spec_); \ - int L = 256 - H; \ - int S = CODING_S(spec_); \ - int D = CODING_D(spec_) - -#define IS_NEG_CODE(S, codeVal) ((((int)(codeVal) + 1) & ((1 << S) - 1)) == 0) - -#define DECODE_SIGN_S1(ux) (((uint32_t)(ux) >> 1) ^ -((int)(ux) & 1)) - -static int decode_sign(int S, uint32_t ux) -{ // == Coding.decodeSign32 - assert(S > 0); - uint32_t sigbits = (ux >> S); - if (IS_NEG_CODE(S, ux)) - return (int)(~sigbits); - else - return (int)(ux - sigbits); - // Note that (int)(ux-sigbits) can be negative, if ux is large enough. -} - -coding *coding::init() -{ - if (umax > 0) - return this; // already done - assert(spec != 0); // sanity - - // fill in derived fields - CODING_PRIVATE(spec); - - // Return nullptr if 'arb(BHSD)' parameter constraints are not met: - if (B < 1 || B > B_MAX) - return nullptr; - if (H < 1 || H > 256) - return nullptr; - if (S < 0 || S > 2) - return nullptr; - if (D < 0 || D > 1) - return nullptr; - if (B == 1 && H != 256) - return nullptr; // 1-byte coding must be fixed-size - if (B >= 5 && H == 256) - return nullptr; // no 5-byte fixed-size coding - - // first compute the range of the coding, in 64 bits - int64_t range = 0; - { - int64_t H_i = 1; - for (int i = 0; i < B; i++) - { - range += H_i; - H_i *= H; - } - range *= L; - range += H_i; - } - assert(range > 0); // no useless codings, please - - int this_umax; - - // now, compute min and max - if (range >= ((int64_t)1 << 32)) - { - this_umax = INT_MAX_VALUE; - this->umin = INT_MIN_VALUE; - this->max = INT_MAX_VALUE; - this->min = INT_MIN_VALUE; - } - else - { - this_umax = (range > INT_MAX_VALUE) ? INT_MAX_VALUE : (int)range - 1; - this->max = this_umax; - this->min = this->umin = 0; - if (S != 0 && range != 0) - { - int64_t maxPosCode = range - 1; - int64_t maxNegCode = range - 1; - while (IS_NEG_CODE(S, maxPosCode)) - --maxPosCode; - while (!IS_NEG_CODE(S, maxNegCode)) - --maxNegCode; - int maxPos = decode_sign(S, (uint32_t)maxPosCode); - if (maxPos < 0) - this->max = INT_MAX_VALUE; // 32-bit wraparound - else - this->max = maxPos; - if (maxNegCode < 0) - this->min = 0; // No negative codings at all. - else - this->min = decode_sign(S, (uint32_t)maxNegCode); - } - } - - assert(!(isFullRange | isSigned | isSubrange)); // init - if (min < 0) - this->isSigned = true; - if (max < INT_MAX_VALUE && range <= INT_MAX_VALUE) - this->isSubrange = true; - if (max == INT_MAX_VALUE && min == INT_MIN_VALUE) - this->isFullRange = true; - - // do this last, to reduce MT exposure (should have a membar too) - this->umax = this_umax; - - return this; -} - -coding *coding::findBySpec(int spec) -{ - for (coding *scan = &basic_codings[0];; scan++) - { - if (scan->spec == spec) - return scan->init(); - if (scan->spec == 0) - break; - } - coding *ptr = NEW(coding, 1); - if (!ptr) - return nullptr; - coding *c = ptr->initFrom(spec); - if (c == nullptr) - { - ::free(ptr); - } - else - // else caller should free it... - c->isMalloc = true; - return c; -} - -coding *coding::findBySpec(int B, int H, int S, int D) -{ - if (B < 1 || B > B_MAX) - return nullptr; - if (H < 1 || H > 256) - return nullptr; - if (S < 0 || S > 2) - return nullptr; - if (D < 0 || D > 1) - return nullptr; - return findBySpec(CODING_SPEC(B, H, S, D)); -} - -void coding::free() -{ - if (isMalloc) - { - ::free(this); - } -} - -void coding_method::reset(value_stream *state) -{ - assert(state->rp == state->rplimit); // not in mid-stream, please - // assert(this == vs0.cm); - state[0] = vs0; - if (uValues != nullptr) - { - uValues->reset(state->helper()); - } -} - -uint32_t coding::parse(byte *&rp, int B, int H) -{ - int L = 256 - H; - byte *ptr = rp; - // hand peel the i==0 part of the loop: - uint32_t b_i = *ptr++ & 0xFF; - if (B == 1 || b_i < (uint32_t)L) - { - rp = ptr; - return b_i; - } - uint32_t sum = b_i; - uint32_t H_i = H; - assert(B <= B_MAX); - for (int i = 2; i <= B_MAX; i++) - { // easy for compilers to unroll if desired - b_i = *ptr++ & 0xFF; - sum += b_i * H_i; - if (i == B || b_i < (uint32_t)L) - { - rp = ptr; - return sum; - } - H_i *= H; - } - assert(false); - return 0; -} - -uint32_t coding::parse_lgH(byte *&rp, int B, int H, int lgH) -{ - assert(H == (1 << lgH)); - int L = 256 - (1 << lgH); - byte *ptr = rp; - // hand peel the i==0 part of the loop: - uint32_t b_i = *ptr++ & 0xFF; - if (B == 1 || b_i < (uint32_t)L) - { - rp = ptr; - return b_i; - } - uint32_t sum = b_i; - uint32_t lg_H_i = lgH; - assert(B <= B_MAX); - for (int i = 2; i <= B_MAX; i++) - { // easy for compilers to unroll if desired - b_i = *ptr++ & 0xFF; - sum += b_i << lg_H_i; - if (i == B || b_i < (uint32_t)L) - { - rp = ptr; - return sum; - } - lg_H_i += lgH; - } - assert(false); - return 0; -} - -static const char ERB[] = "EOF reading band"; - -void coding::parseMultiple(byte *&rp, int N, byte *limit, int B, int H) -{ - if (N < 0) - { - unpack_abort("bad value count"); - return; - } - byte *ptr = rp; - if (B == 1 || H == 256) - { - size_t len = (size_t)N * B; - if (len / B != (size_t)N || ptr + len > limit) - { - unpack_abort(ERB); - return; - } - rp = ptr + len; - return; - } - // Note: We assume rp has enough zero-padding. - int L = 256 - H; - int n = B; - while (N > 0) - { - ptr += 1; - if (--n == 0) - { - // end of encoding at B bytes, regardless of byte value - } - else - { - int b = (ptr[-1] & 0xFF); - if (b >= L) - { - // keep going, unless we find a byte < L - continue; - } - } - // found the last byte - N -= 1; - n = B; // reset length counter - // do an error check here - if (ptr > limit) - { - unpack_abort(ERB); - return; - } - } - rp = ptr; - return; -} - -bool value_stream::hasHelper() -{ - // If my coding method is a pop-style method, - // then I need a second value stream to transmit - // unfavored values. - // This can be determined by examining fValues. - return cm->fValues != nullptr; -} - -void value_stream::init(byte *rp_, byte *rplimit_, coding *defc) -{ - rp = rp_; - rplimit = rplimit_; - sum = 0; - cm = nullptr; // no need in the simple case - setCoding(defc); -} - -void value_stream::setCoding(coding *defc) -{ - if (defc == nullptr) - { - unpack_abort("bad coding"); - defc = coding::findByIndex(_meta_canon_min); // random pick for recovery - } - - c = (*defc); - - // choose cmk - cmk = cmk_ERROR; - switch (c.spec) - { - case BYTE1_spec: - cmk = cmk_BYTE1; - break; - case CHAR3_spec: - cmk = cmk_CHAR3; - break; - case UNSIGNED5_spec: - cmk = cmk_UNSIGNED5; - break; - case DELTA5_spec: - cmk = cmk_DELTA5; - break; - case BCI5_spec: - cmk = cmk_BCI5; - break; - case BRANCH5_spec: - cmk = cmk_BRANCH5; - break; - default: - if (c.D() == 0) - { - switch (c.S()) - { - case 0: - cmk = cmk_BHS0; - break; - case 1: - cmk = cmk_BHS1; - break; - default: - cmk = cmk_BHS; - break; - } - } - else - { - if (c.S() == 1) - { - if (c.isFullRange) - cmk = cmk_BHS1D1full; - if (c.isSubrange) - cmk = cmk_BHS1D1sub; - } - if (cmk == cmk_ERROR) - cmk = cmk_BHSD1; - } - } -} - -static int getPopValue(value_stream *self, uint32_t uval) -{ - if (uval > 0) - { - // note that the initial parse performed a range check - assert(uval <= (uint32_t)self->cm->fVlength); - return self->cm->fValues[uval - 1]; - } - else - { - // take an unfavored value - return self->helper()->getInt(); - } -} - -int coding::sumInUnsignedRange(int x, int y) -{ - assert(isSubrange); - int range = (int)(umax + 1); - assert(range > 0); - x += y; - if (x != (int)((int64_t)(x - y) + (int64_t)y)) - { - // 32-bit overflow interferes with range reduction. - // Back off from the overflow by adding a multiple of range: - if (x < 0) - { - x -= range; - assert(x >= 0); - } - else - { - x += range; - assert(x < 0); - } - } - if (x < 0) - { - x += range; - if (x >= 0) - return x; - } - else if (x >= range) - { - x -= range; - if (x < range) - return x; - } - else - { - // in range - return x; - } - // do it the hard way - x %= range; - if (x < 0) - x += range; - return x; -} - -static int getDeltaValue(value_stream *self, uint32_t uval, bool isSubrange) -{ - assert((uint32_t)(self->c.isSubrange) == (uint32_t)isSubrange); - assert(self->c.isSubrange | self->c.isFullRange); - if (isSubrange) - return self->sum = self->c.sumInUnsignedRange(self->sum, (int)uval); - else - return self->sum += (int)uval; -} - -bool value_stream::hasValue() -{ - if (rp < rplimit) - return true; - if (cm == nullptr) - return false; - if (cm->next == nullptr) - return false; - cm->next->reset(this); - return hasValue(); -} - -int value_stream::getInt() -{ - if (rp >= rplimit) - { - // Advance to next coding segment. - if (rp > rplimit || cm == nullptr || cm->next == nullptr) - { - // Must perform this check and throw an exception on bad input. - unpack_abort(ERB); - return 0; - } - cm->next->reset(this); - return getInt(); - } - - CODING_PRIVATE(c.spec); - uint32_t uval; - enum - { - B5 = 5, - B3 = 3, - H128 = 128, - H64 = 64, - H4 = 4 - }; - switch (cmk) - { - case cmk_BHS: - assert(D == 0); - uval = coding::parse(rp, B, H); - if (S == 0) - return (int)uval; - return decode_sign(S, uval); - - case cmk_BHS0: - assert(S == 0 && D == 0); - uval = coding::parse(rp, B, H); - return (int)uval; - - case cmk_BHS1: - assert(S == 1 && D == 0); - uval = coding::parse(rp, B, H); - return DECODE_SIGN_S1(uval); - - case cmk_BYTE1: - assert(c.spec == BYTE1_spec); - assert(B == 1 && H == 256 && S == 0 && D == 0); - return *rp++ & 0xFF; - - case cmk_CHAR3: - assert(c.spec == CHAR3_spec); - assert(B == B3 && H == H128 && S == 0 && D == 0); - return coding::parse_lgH(rp, B3, H128, 7); - - case cmk_UNSIGNED5: - assert(c.spec == UNSIGNED5_spec); - assert(B == B5 && H == H64 && S == 0 && D == 0); - return coding::parse_lgH(rp, B5, H64, 6); - - case cmk_BHSD1: - assert(D == 1); - uval = coding::parse(rp, B, H); - if (S != 0) - uval = (uint32_t)decode_sign(S, uval); - return getDeltaValue(this, uval, (bool)c.isSubrange); - - case cmk_BHS1D1full: - assert(S == 1 && D == 1 && c.isFullRange); - uval = coding::parse(rp, B, H); - uval = (uint32_t)DECODE_SIGN_S1(uval); - return getDeltaValue(this, uval, false); - - case cmk_BHS1D1sub: - assert(S == 1 && D == 1 && c.isSubrange); - uval = coding::parse(rp, B, H); - uval = (uint32_t)DECODE_SIGN_S1(uval); - return getDeltaValue(this, uval, true); - - case cmk_DELTA5: - assert(c.spec == DELTA5_spec); - assert(B == B5 && H == H64 && S == 1 && D == 1 && c.isFullRange); - uval = coding::parse_lgH(rp, B5, H64, 6); - sum += DECODE_SIGN_S1(uval); - return sum; - - case cmk_BCI5: - assert(c.spec == BCI5_spec); - assert(B == B5 && H == H4 && S == 0 && D == 0); - return coding::parse_lgH(rp, B5, H4, 2); - - case cmk_BRANCH5: - assert(c.spec == BRANCH5_spec); - assert(B == B5 && H == H4 && S == 2 && D == 0); - uval = coding::parse_lgH(rp, B5, H4, 2); - return decode_sign(S, uval); - - case cmk_pop: - uval = coding::parse(rp, B, H); - if (S != 0) - { - uval = (uint32_t)decode_sign(S, uval); - } - if (D != 0) - { - assert(c.isSubrange | c.isFullRange); - if (c.isSubrange) - sum = c.sumInUnsignedRange(sum, (int)uval); - else - sum += (int)uval; - uval = (uint32_t)sum; - } - return getPopValue(this, uval); - - case cmk_pop_BHS0: - assert(S == 0 && D == 0); - uval = coding::parse(rp, B, H); - return getPopValue(this, uval); - - case cmk_pop_BYTE1: - assert(c.spec == BYTE1_spec); - assert(B == 1 && H == 256 && S == 0 && D == 0); - return getPopValue(this, *rp++ & 0xFF); - - default: - break; - } - assert(false); - return 0; -} - -static int moreCentral(int x, int y) -{ // used to find end of Pop.{F} - // Suggested implementation from the Pack200 specification: - uint32_t kx = (x >> 31) ^ (x << 1); - uint32_t ky = (y >> 31) ^ (y << 1); - return (kx < ky ? x : y); -} -// static maybe_inline -// int moreCentral2(int x, int y, int min) { -// // Strict implementation of buggy 150.7 specification. -// // The bug is that the spec. says absolute-value ties are broken -// // in favor of positive numbers, but the suggested implementation -// // (also mentioned in the spec.) breaks ties in favor of negative numbers. -// if ((x + y) != 0) -// return min; -// else -// // return the other value, which breaks a tie in the positive direction -// return (x > y)? x: y; -//} - -static const byte *no_meta[] = {nullptr}; -#define NO_META (*(byte **)no_meta) -enum -{ - POP_FAVORED_N = -2 -}; - -// mode bits -#define DISABLE_RUN 1 // used immediately inside ACodee -#define DISABLE_POP 2 // used recursively in all pop sub-bands - -// This function knows all about meta-coding. -void coding_method::init(byte *&band_rp, byte *band_limit, byte *&meta_rp, int mode, - coding *defc, int N, intlist *valueSink) -{ - assert(N != 0); - - assert(u != nullptr); // must be pre-initialized - // if (u == nullptr) u = unpacker::current(); // expensive - - int op = (meta_rp == nullptr) ? _meta_default : (*meta_rp++ & 0xFF); - coding *foundc = nullptr; - coding *to_free = nullptr; - - if (op == _meta_default) - { - foundc = defc; - // and fall through - } - else if (op >= _meta_canon_min && op <= _meta_canon_max) - { - foundc = coding::findByIndex(op); - // and fall through - } - else if (op == _meta_arb) - { - int args = (*meta_rp++ & 0xFF); - // args = (D:[0..1] + 2*S[0..2] + 8*(B:[1..5]-1)) - int D = ((args >> 0) & 1); - int S = ((args >> 1) & 3); - int B = ((args >> 3) & -1) + 1; - // & (H[1..256]-1) - int H = (*meta_rp++ & 0xFF) + 1; - foundc = coding::findBySpec(B, H, S, D); - to_free = foundc; // findBySpec may dynamically allocate - if (foundc == nullptr) - { - unpack_abort("illegal arbitrary coding"); - return; - } - // and fall through - } - else if (op >= _meta_run && op < _meta_pop) - { - int args = (op - _meta_run); - // args: KX:[0..3] + 4*(KBFlag:[0..1]) + 8*(ABDef:[0..2]) - int KX = ((args >> 0) & 3); - int KBFlag = ((args >> 2) & 1); - int ABDef = ((args >> 3) & -1); - assert(ABDef <= 2); - // & KB: one of [0..255] if KBFlag=1 - int KB = (!KBFlag ? 3 : (*meta_rp++ & 0xFF)); - int K = (KB + 1) << (KX * 4); - int N2 = (N >= 0) ? N - K : N; - if (N == 0 || (N2 <= 0 && N2 != N)) - { - unpack_abort("illegal run encoding"); - } - if ((mode & DISABLE_RUN) != 0) - { - unpack_abort("illegal nested run encoding"); - } - - // & Enc{ ACode } if ADef=0 (ABDef != 1) - // No direct nesting of 'run' in ACode, but in BCode it's OK. - int disRun = mode | DISABLE_RUN; - if (ABDef == 1) - { - this->init(band_rp, band_limit, NO_META, disRun, defc, K, valueSink); - } - else - { - this->init(band_rp, band_limit, meta_rp, disRun, defc, K, valueSink); - } - - // & Enc{ BCode } if BDef=0 (ABDef != 2) - coding_method *tail = U_NEW(coding_method, 1); - if (!tail) - return; - tail->u = u; - - // The 'run' codings may be nested indirectly via 'pop' codings. - // This means that this->next may already be filled in, if - // ACode was of type 'pop' with a 'run' token coding. - // No problem: Just chain the upcoming BCode onto the end. - for (coding_method *self = this;; self = self->next) - { - if (self->next == nullptr) - { - self->next = tail; - break; - } - } - - if (ABDef == 2) - { - tail->init(band_rp, band_limit, NO_META, mode, defc, N2, valueSink); - } - else - { - tail->init(band_rp, band_limit, meta_rp, mode, defc, N2, valueSink); - } - // Note: The preceding calls to init should be tail-recursive. - - return; // done; no falling through - } - else if (op >= _meta_pop && op < _meta_limit) - { - int args = (op - _meta_pop); - // args: (FDef:[0..1]) + 2*UDef:[0..1] + 4*(TDefL:[0..11]) - int FDef = ((args >> 0) & 1); - int UDef = ((args >> 1) & 1); - int TDefL = ((args >> 2) & -1); - assert(TDefL <= 11); - int TDef = (TDefL > 0); - int TL = (TDefL <= 6) ? (2 << TDefL) : (256 - (4 << (11 - TDefL))); - int TH = (256 - TL); - if (N <= 0) - { - unpack_abort("illegal pop encoding"); - } - if ((mode & DISABLE_POP) != 0) - { - unpack_abort("illegal nested pop encoding"); - } - - // No indirect nesting of 'pop', but 'run' is OK. - int disPop = DISABLE_POP; - - // & Enc{ FCode } if FDef=0 - int FN = POP_FAVORED_N; - assert(valueSink == nullptr); - intlist fValueSink; - fValueSink.init(); - coding_method fval; - BYTES_OF(fval).clear(); - fval.u = u; - if (FDef != 0) - { - fval.init(band_rp, band_limit, NO_META, disPop, defc, FN, &fValueSink); - } - else - { - fval.init(band_rp, band_limit, meta_rp, disPop, defc, FN, &fValueS