1782 }
1783 band_stack.popTo(bs_base);
1784 return res;
1785 }
1786 }
1787
1788 const char*
1789 unpacker::attr_definitions::parseLayout(const char* lp, band** &res,
1790 int curCble) {
1791 const char* lp0 = lp;
1792 int bs_base = band_stack.length();
1793 bool top_level = (bs_base == 0);
1794 band* b;
1795 enum { can_be_signed = true }; // optional arg to parseIntLayout
1796
1797 for (bool done = false; !done; ) {
1798 switch (*lp++) {
1799 case 'B': case 'H': case 'I': case 'V': // unsigned_int
1800 case 'S': // signed_int
1801 --lp; // reparse
1802 case 'F':
1803 lp = parseIntLayout(lp, b, EK_INT);
1804 break;
1805 case 'P':
1806 {
1807 int le_bci = EK_BCI;
1808 if (*lp == 'O') {
1809 ++lp;
1810 le_bci = EK_BCID;
1811 }
1812 assert(*lp != 'S'); // no PSH, etc.
1813 lp = parseIntLayout(lp, b, EK_INT);
1814 b->le_bci = le_bci;
1815 if (le_bci == EK_BCI)
1816 b->defc = coding::findBySpec(BCI5_spec);
1817 else
1818 b->defc = coding::findBySpec(BRANCH5_spec);
1819 }
1820 break;
1821 case 'O':
3693 static bytes& getbuf(size_t len) { // for debugging only!
3694 static int bn = 0;
3695 static bytes bufs[8];
3696 bytes& buf = bufs[bn++ & 7];
3697 while (buf.len < len + 10) {
3698 buf.realloc(buf.len ? buf.len * 2 : 1000);
3699 }
3700 buf.ptr[0] = 0; // for the sake of strcat
3701 return buf;
3702 }
3703
3704 const char* entry::string() {
3705 bytes buf;
3706 switch (tag) {
3707 case CONSTANT_None:
3708 return "<empty>";
3709 case CONSTANT_Signature:
3710 if (value.b.ptr == null)
3711 return ref(0)->string();
3712 // else fall through:
3713 case CONSTANT_Utf8:
3714 buf = value.b;
3715 break;
3716 case CONSTANT_Integer:
3717 case CONSTANT_Float:
3718 buf = getbuf(12);
3719 sprintf((char*)buf.ptr, "0x%08x", value.i);
3720 break;
3721 case CONSTANT_Long:
3722 case CONSTANT_Double:
3723 buf = getbuf(24);
3724 sprintf((char*)buf.ptr, "0x" LONG_LONG_HEX_FORMAT, value.l);
3725 break;
3726 default:
3727 if (nrefs == 0) {
3728 return TAG_NAME[tag];
3729 } else if (nrefs == 1) {
3730 return refs[0]->string();
3731 } else {
3732 const char* s1 = refs[0]->string();
4199 }
4200 case bc_byte_escape:
4201 {
4202 // Note that insnMap has one entry for all these bytes.
4203 --wp; // not really part of the code
4204 int size = bc_escsize.getInt();
4205 if (size < 0) { assert(false); continue; }
4206 ensure_put_space(size);
4207 for (int j = 0; j < size; j++)
4208 putu1_fast(bc_escbyte.getByte());
4209 continue;
4210 }
4211 default:
4212 if (is_invoke_init_op(bc)) {
4213 origBC = bc_invokespecial;
4214 entry* classRef;
4215 switch (bc - _invokeinit_op) {
4216 case _invokeinit_self_option: classRef = thisClass; break;
4217 case _invokeinit_super_option: classRef = superClass; break;
4218 default: assert(bc == _invokeinit_op+_invokeinit_new_option);
4219 case _invokeinit_new_option: classRef = newClass; break;
4220 }
4221 wp[-1] = origBC; // overwrite with origBC
4222 int coding = bc_initref.getInt();
4223 // Find the nth overloading of <init> in classRef.
4224 entry* ref = null;
4225 cpindex* ix = cp.getMethodIndex(classRef);
4226 CHECK;
4227 for (int j = 0, which_init = 0; ; j++) {
4228 ref = (ix == null)? null: ix->get(j);
4229 if (ref == null) break; // oops, bad input
4230 assert(ref->tag == CONSTANT_Methodref);
4231 if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) {
4232 if (which_init++ == coding) break;
4233 }
4234 }
4235 putref(ref);
4236 continue;
4237 }
4238 bc_which = ref_band_for_self_op(bc, isAload, origBC);
|
1782 }
1783 band_stack.popTo(bs_base);
1784 return res;
1785 }
1786 }
1787
1788 const char*
1789 unpacker::attr_definitions::parseLayout(const char* lp, band** &res,
1790 int curCble) {
1791 const char* lp0 = lp;
1792 int bs_base = band_stack.length();
1793 bool top_level = (bs_base == 0);
1794 band* b;
1795 enum { can_be_signed = true }; // optional arg to parseIntLayout
1796
1797 for (bool done = false; !done; ) {
1798 switch (*lp++) {
1799 case 'B': case 'H': case 'I': case 'V': // unsigned_int
1800 case 'S': // signed_int
1801 --lp; // reparse
1802 /* fall through */
1803 case 'F':
1804 lp = parseIntLayout(lp, b, EK_INT);
1805 break;
1806 case 'P':
1807 {
1808 int le_bci = EK_BCI;
1809 if (*lp == 'O') {
1810 ++lp;
1811 le_bci = EK_BCID;
1812 }
1813 assert(*lp != 'S'); // no PSH, etc.
1814 lp = parseIntLayout(lp, b, EK_INT);
1815 b->le_bci = le_bci;
1816 if (le_bci == EK_BCI)
1817 b->defc = coding::findBySpec(BCI5_spec);
1818 else
1819 b->defc = coding::findBySpec(BRANCH5_spec);
1820 }
1821 break;
1822 case 'O':
3694 static bytes& getbuf(size_t len) { // for debugging only!
3695 static int bn = 0;
3696 static bytes bufs[8];
3697 bytes& buf = bufs[bn++ & 7];
3698 while (buf.len < len + 10) {
3699 buf.realloc(buf.len ? buf.len * 2 : 1000);
3700 }
3701 buf.ptr[0] = 0; // for the sake of strcat
3702 return buf;
3703 }
3704
3705 const char* entry::string() {
3706 bytes buf;
3707 switch (tag) {
3708 case CONSTANT_None:
3709 return "<empty>";
3710 case CONSTANT_Signature:
3711 if (value.b.ptr == null)
3712 return ref(0)->string();
3713 // else fall through:
3714 /* fall through */
3715 case CONSTANT_Utf8:
3716 buf = value.b;
3717 break;
3718 case CONSTANT_Integer:
3719 case CONSTANT_Float:
3720 buf = getbuf(12);
3721 sprintf((char*)buf.ptr, "0x%08x", value.i);
3722 break;
3723 case CONSTANT_Long:
3724 case CONSTANT_Double:
3725 buf = getbuf(24);
3726 sprintf((char*)buf.ptr, "0x" LONG_LONG_HEX_FORMAT, value.l);
3727 break;
3728 default:
3729 if (nrefs == 0) {
3730 return TAG_NAME[tag];
3731 } else if (nrefs == 1) {
3732 return refs[0]->string();
3733 } else {
3734 const char* s1 = refs[0]->string();
4201 }
4202 case bc_byte_escape:
4203 {
4204 // Note that insnMap has one entry for all these bytes.
4205 --wp; // not really part of the code
4206 int size = bc_escsize.getInt();
4207 if (size < 0) { assert(false); continue; }
4208 ensure_put_space(size);
4209 for (int j = 0; j < size; j++)
4210 putu1_fast(bc_escbyte.getByte());
4211 continue;
4212 }
4213 default:
4214 if (is_invoke_init_op(bc)) {
4215 origBC = bc_invokespecial;
4216 entry* classRef;
4217 switch (bc - _invokeinit_op) {
4218 case _invokeinit_self_option: classRef = thisClass; break;
4219 case _invokeinit_super_option: classRef = superClass; break;
4220 default: assert(bc == _invokeinit_op+_invokeinit_new_option);
4221 /* fall through */
4222 case _invokeinit_new_option: classRef = newClass; break;
4223 }
4224 wp[-1] = origBC; // overwrite with origBC
4225 int coding = bc_initref.getInt();
4226 // Find the nth overloading of <init> in classRef.
4227 entry* ref = null;
4228 cpindex* ix = cp.getMethodIndex(classRef);
4229 CHECK;
4230 for (int j = 0, which_init = 0; ; j++) {
4231 ref = (ix == null)? null: ix->get(j);
4232 if (ref == null) break; // oops, bad input
4233 assert(ref->tag == CONSTANT_Methodref);
4234 if (ref->memberDescr()->descrName() == cp.sym[cpool::s_lt_init_gt]) {
4235 if (which_init++ == coding) break;
4236 }
4237 }
4238 putref(ref);
4239 continue;
4240 }
4241 bc_which = ref_band_for_self_op(bc, isAload, origBC);
|