Skip to content

Commit f518b4b

Browse files
committed
Cleanup type conversions in java_bytecode_parsert::read
We can safely read signed values and don't need to defer the type conversion to the call site.
1 parent 66004dc commit f518b4b

File tree

1 file changed

+27
-17
lines changed

1 file changed

+27
-17
lines changed

jbmc/src/java_bytecode/java_bytecode_parser.cpp

+27-17
Original file line numberDiff line numberDiff line change
@@ -132,9 +132,19 @@ class java_bytecode_parsert final : public parsert
132132
T read()
133133
{
134134
static_assert(
135-
std::is_unsigned<T>::value, "T should be an unsigned integer");
135+
std::is_unsigned<T>::value || std::is_signed<T>::value,
136+
"T should be a signed or unsigned integer");
136137
const constexpr size_t bytes = sizeof(T);
137-
u8 result = 0;
138+
if(bytes == 1)
139+
{
140+
if(!*in)
141+
{
142+
log.error() << "unexpected end of bytecode file" << messaget::eom;
143+
throw 0;
144+
}
145+
return static_cast<T>(in->get());
146+
}
147+
T result = 0;
138148
for(size_t i = 0; i < bytes; i++)
139149
{
140150
if(!*in)
@@ -145,7 +155,7 @@ class java_bytecode_parsert final : public parsert
145155
result <<= 8u;
146156
result |= static_cast<u1>(in->get());
147157
}
148-
return narrow_cast<T>(result);
158+
return result;
149159
}
150160

151161
void store_unknown_method_handle(size_t bootstrap_method_index);
@@ -700,7 +710,7 @@ void java_bytecode_parsert::rconstant_pool()
700710
std::string s;
701711
s.resize(bytes);
702712
for(auto &ch : s)
703-
ch = read<u1>();
713+
ch = read<std::string::value_type>();
704714
it->s = s; // Add to string table
705715
}
706716
break;
@@ -942,15 +952,15 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
942952

943953
case 'b': // a signed byte
944954
{
945-
const s1 c = read<u1>();
955+
const s1 c = read<s1>();
946956
instruction.args.push_back(from_integer(c, signedbv_typet(8)));
947957
}
948958
address+=1;
949959
break;
950960

951961
case 'o': // two byte branch offset, signed
952962
{
953-
const s2 offset = read<u2>();
963+
const s2 offset = read<s2>();
954964
// By converting the signed offset into an absolute address (by adding
955965
// the current address) the number represented becomes unsigned.
956966
instruction.args.push_back(
@@ -961,7 +971,7 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
961971

962972
case 'O': // four byte branch offset, signed
963973
{
964-
const s4 offset = read<u4>();
974+
const s4 offset = read<s4>();
965975
// By converting the signed offset into an absolute address (by adding
966976
// the current address) the number represented becomes unsigned.
967977
instruction.args.push_back(
@@ -994,15 +1004,15 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
9941004
{
9951005
const u2 v = read<u2>();
9961006
instruction.args.push_back(from_integer(v, unsignedbv_typet(16)));
997-
const s2 c = read<u2>();
1007+
const s2 c = read<s2>();
9981008
instruction.args.push_back(from_integer(c, signedbv_typet(16)));
9991009
address+=4;
10001010
}
10011011
else // local variable index (one byte) plus one signed byte
10021012
{
10031013
const u1 v = read<u1>();
10041014
instruction.args.push_back(from_integer(v, unsignedbv_typet(8)));
1005-
const s1 c = read<u1>();
1015+
const s1 c = read<s1>();
10061016
instruction.args.push_back(from_integer(c, signedbv_typet(8)));
10071017
address+=2;
10081018
}
@@ -1032,7 +1042,7 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10321042
}
10331043

10341044
// now default value
1035-
const s4 default_value = read<u4>();
1045+
const s4 default_value = read<s4>();
10361046
// By converting the signed offset into an absolute address (by adding
10371047
// the current address) the number represented becomes unsigned.
10381048
instruction.args.push_back(
@@ -1045,8 +1055,8 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10451055

10461056
for(std::size_t i=0; i<npairs; i++)
10471057
{
1048-
const s4 match = read<u4>();
1049-
const s4 offset = read<u4>();
1058+
const s4 match = read<s4>();
1059+
const s4 offset = read<s4>();
10501060
instruction.args.push_back(
10511061
from_integer(match, signedbv_typet(32)));
10521062
// By converting the signed offset into an absolute address (by adding
@@ -1070,23 +1080,23 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
10701080
}
10711081

10721082
// now default value
1073-
const s4 default_value = read<u4>();
1083+
const s4 default_value = read<s4>();
10741084
instruction.args.push_back(
10751085
from_integer(base_offset+default_value, signedbv_typet(32)));
10761086
address+=4;
10771087

10781088
// now low value
1079-
const s4 low_value = read<u4>();
1089+
const s4 low_value = read<s4>();
10801090
address+=4;
10811091

10821092
// now high value
1083-
const s4 high_value = read<u4>();
1093+
const s4 high_value = read<s4>();
10841094
address+=4;
10851095

10861096
// there are high-low+1 offsets, and they are signed
10871097
for(s4 i=low_value; i<=high_value; i++)
10881098
{
1089-
s4 offset = read<u4>();
1099+
s4 offset = read<s4>();
10901100
instruction.args.push_back(from_integer(i, signedbv_typet(32)));
10911101
// By converting the signed offset into an absolute address (by adding
10921102
// the current address) the number represented becomes unsigned.
@@ -1130,7 +1140,7 @@ void java_bytecode_parsert::rbytecode(std::vector<instructiont> &instructions)
11301140

11311141
case 's': // a signed short
11321142
{
1133-
const s2 s = read<u2>();
1143+
const s2 s = read<s2>();
11341144
instruction.args.push_back(from_integer(s, signedbv_typet(16)));
11351145
}
11361146
address+=2;

0 commit comments

Comments
 (0)