/* -------------------------------------------------------------- javel - A java class file disassembler. Copyright (C) 2001 Laurent Gregoire (l.gregoire@iname.com) -------------------------------------------------------------- This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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 for more details. -------------------------------------------------------------- */ #include #include #include "cp_info.h" #include "class_info.h" /** Set this symbol if you want to dump float values in the s.m.2^m form: */ #undef DUMP_FLOAT /** Same for double: */ #undef DUMP_DOUBLE /** This symbol is named something else on some other platforms. */ typedef long long llong; void cp_class_info::get(istream& is) { name_index = util::read_U2(is); } string cp_class_info::str() const { return ci->get_cp_info(name_index)->str(); } void cp_class_info::makedepend(depend_list& di) const { di[str()] = true; } void cp_utf8_info::get(istream& is) { ostringstream ost; U2 length = util::read_U2(is); U1* bytes = new U1[length + 1]; for (int i = 0; i < length; i++) { bytes[i] = util::read_U1(is); } bytes[length] = '\0'; ost << bytes; delete bytes; utf8 = ost.str(); } string cp_utf8_info::str() const { return utf8; } void cp_nameandtype_info::get(istream& is) { name_index = util::read_U2(is); descriptor_index = util::read_U2(is); } string cp_nameandtype_info::str() const { return ci->get_cp_info(name_index)->str(); } void cp_nameandtype_info::makedepend(depend_list& di) const { } void cp_methodref_info::makedepend(depend_list& di) const { } void cp_xxxref_info::get(istream& is) { class_index = util::read_U2(is); name_and_type_index = util::read_U2(is); } string cp_xxxref_info::str() const { return ci->get_cp_info(name_and_type_index)->str(); } void cp_string_info::get(istream& is) { string_index = util::read_U2(is); } void cp_integer_info::get(istream& is) { bytes = util::read_U4(is); } string cp_integer_info::str() const { ostringstream ost; ost << bytes; return ost.str(); } void cp_float_info::get(istream& is) { bytes = util::read_U4(is); } string cp_float_info::str() const { ostringstream ost; if (bytes == 0x7f800000) { ost << "<+inf>"; } else if (bytes == 0xff800000) { ost << "<-inf>"; } else if ((bytes >= 0x7f800001 && bytes <= 0x7fffffff) || (bytes >= 0xff800001 && bytes <= 0xffffffff)) { ost << ""; } else { int sign = ((bytes >> 31) == 0) ? 1 : -1; int expo = ((bytes >> 23) & 0xff); int mant = (expo == 0) ? (bytes & 0x7fffff) << 1 : (bytes & 0x7fffff) | 0x800000; expo -= 150; double x = sign; x *= mant; x *= pow(2.0, expo); ost << x << "F"; #ifdef DUMP_FLOAT ost << " /* "; if (sign == -1) ost << "-"; ost << mant << ".2^" << expo << " */ "; #endif } return ost.str(); } void cp_long_info::get(istream& is) { high_bytes = util::read_U4(is); low_bytes = util::read_U4(is); } string cp_long_info::str() const { ostringstream ost; llong n = (llong)low_bytes + ((llong)high_bytes << 32); ost << n << "L"; return ost.str(); } void cp_double_info::get(istream& is) { high_bytes = util::read_U4(is); low_bytes = util::read_U4(is); } string cp_double_info::str() const { ostringstream ost; if (high_bytes == 0x7ff00000 && low_bytes == 0x00000000) { ost << "<+inf>"; } else if (high_bytes == 0xfff00000 && low_bytes == 0x00000000) { ost << "<-inf>"; } else if ((high_bytes & 0xfff00000 == 0x7ff00000) || (high_bytes & 0xfff00000 == 0xfff00000)) { ost << ""; } else { llong bytes = ((llong)low_bytes + ((llong)high_bytes << 32)); int sign = ((high_bytes >> 31) == 0) ? 1 : -1; int expo = (high_bytes >> 20) & 0x7ff; expo -= 1075; llong mant = (expo == 0) ? (bytes & 0xfffffffffffffLL) << 1 : (bytes & 0xfffffffffffffLL) | 0x10000000000000LL; long double x = sign; x *= mant; x *= pow(2.0, expo); ost << x << "D"; #ifdef DUMP_DOUBLE ost << " /* "; if (sign == -1) ost << "-"; ost << mant << ".2^" << expo << " */ "; #endif } return ost.str(); }