Skip to content

Commit 91e7265

Browse files
author
thk123
committed
Replace defines with an enum per table
This is more precise, shows up errors (e.g. trying to read whether a class is protected, when no such concept exists in Java, and doesn't run the risk of different tables using different bit flags for the same concept.
1 parent a29328d commit 91e7265

File tree

1 file changed

+147
-56
lines changed

1 file changed

+147
-56
lines changed

jbmc/src/java_bytecode/java_bytecode_parser.cpp

Lines changed: 147 additions & 56 deletions
Original file line numberDiff line numberDiff line change
@@ -444,28 +444,37 @@ bool java_bytecode_parsert::parse()
444444
return false;
445445
}
446446

447-
#define ACC_PUBLIC 0x0001
448-
#define ACC_PRIVATE 0x0002
449-
#define ACC_PROTECTED 0x0004
450-
#define ACC_STATIC 0x0008
451-
#define ACC_FINAL 0x0010
452-
#define ACC_SYNCHRONIZED 0x0020
453-
#define ACC_BRIDGE 0x0040
454-
#define ACC_VARARGS 0x0080
455-
#define ACC_NATIVE 0x0100
456-
#define ACC_INTERFACE 0x0200
457-
#define ACC_ABSTRACT 0x0400
458-
#define ACC_STRICT 0x0800
459-
#define ACC_SYNTHETIC 0x1000
460-
#define ACC_ANNOTATION 0x2000
461-
#define ACC_ENUM 0x4000
462-
463447
#ifdef _MSC_VER
464448
#define UNUSED
465449
#else
466450
#define UNUSED __attribute__((unused))
467451
#endif
468452

453+
/// Represents the bit flag from class access and property flags
454+
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.1-200-E.1
455+
namespace class_access_flagst
456+
{
457+
enum class_access_flagst
458+
{
459+
/// Declared public; may be accessed from outside its package.
460+
PUBLIC = 0x0001,
461+
/// Declared final; no subclasses allowed.
462+
FINAL = 0x0010,
463+
/// Treat superclass methods specially when invoked by the invokespecial instruction.
464+
SUPER = 0x0020,
465+
/// Is an interface, not a class.
466+
INTERFACE = 0x0200,
467+
/// Declared abstract; must not be instantiated.
468+
ABSTRACT = 0x0400,
469+
/// Declared synthetic; not present in the source code.
470+
SYNTHETIC = 0x1000,
471+
/// Declared as an annotation type.
472+
ANNOTATION = 0x2000,
473+
/// Declared as an enum type.
474+
ENUM = 0x4000,
475+
};
476+
}
477+
469478
void java_bytecode_parsert::rClassFile()
470479
{
471480
parse_tree.loading_successful=false;
@@ -494,15 +503,17 @@ void java_bytecode_parsert::rClassFile()
494503
u2 this_class=read_u2();
495504
u2 super_class=read_u2();
496505

497-
parsed_class.is_abstract=(access_flags&ACC_ABSTRACT)!=0;
498-
parsed_class.is_enum=(access_flags&ACC_ENUM)!=0;
499-
parsed_class.is_public=(access_flags&ACC_PUBLIC)!=0;
500-
parsed_class.is_protected=(access_flags&ACC_PROTECTED)!=0;
501-
parsed_class.is_private=(access_flags&ACC_PRIVATE)!=0;
502-
parsed_class.is_final = (access_flags & ACC_FINAL) != 0;
503-
parsed_class.is_interface = (access_flags & ACC_INTERFACE) != 0;
504-
parsed_class.is_synthetic = (access_flags & ACC_SYNTHETIC) != 0;
505-
parsed_class.is_annotation = (access_flags & ACC_ANNOTATION) != 0;
506+
parsed_class.is_abstract =
507+
(access_flags & class_access_flagst::ABSTRACT) != 0;
508+
parsed_class.is_enum = (access_flags & class_access_flagst::ENUM) != 0;
509+
parsed_class.is_public = (access_flags & class_access_flagst::PUBLIC) != 0;
510+
parsed_class.is_final = (access_flags & class_access_flagst::FINAL) != 0;
511+
parsed_class.is_interface =
512+
(access_flags & class_access_flagst::INTERFACE) != 0;
513+
parsed_class.is_synthetic =
514+
(access_flags & class_access_flagst::SYNTHETIC) != 0;
515+
parsed_class.is_annotation =
516+
(access_flags & class_access_flagst::ANNOTATION) != 0;
506517
parsed_class.name=
507518
constant(this_class).type().get(ID_C_base_name);
508519

@@ -870,6 +881,33 @@ void java_bytecode_parsert::rinterfaces(classt &parsed_class)
870881
.push_back(constant(read_u2()).type().get(ID_C_base_name));
871882
}
872883

884+
/// Represents the bit flag from field access and property flags
885+
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.5-200-A.1
886+
namespace field_access_flagst
887+
{
888+
enum field_access_flagst
889+
{
890+
/// Declared public; may be accessed from outside its package.
891+
PUBLIC = 0x0001,
892+
/// Declared private; usable only within the defining class.
893+
PRIVATE = 0x0002,
894+
/// Declared protected; may be accessed within subclasses.
895+
PROTECTED = 0x0004,
896+
/// Declared static.
897+
STATIC = 0x0008,
898+
/// Declared final; never directly assigned to after object construction (JLS §17.5).
899+
FINAL = 0x0010,
900+
/// Declared volatile; cannot be cached.
901+
VOLATILE = 0x0040,
902+
/// Declared transient; not written or read by a persistent object manager.
903+
TRANSIENT = 0x0080,
904+
/// Declared synthetic; not present in the source code.
905+
SYNTHETIC = 0x1000,
906+
/// Declared as an element of an enum.
907+
ENUM = 0x4000
908+
};
909+
}
910+
873911
void java_bytecode_parsert::rfields(classt &parsed_class)
874912
{
875913
u2 fields_count=read_u2();
@@ -884,14 +922,14 @@ void java_bytecode_parsert::rfields(classt &parsed_class)
884922
u2 attributes_count=read_u2();
885923

886924
field.name=pool_entry(name_index).s;
887-
field.is_static=(access_flags&ACC_STATIC)!=0;
888-
field.is_final=(access_flags&ACC_FINAL)!=0;
889-
field.is_enum=(access_flags&ACC_ENUM)!=0;
925+
field.is_static = (access_flags & field_access_flagst::STATIC) != 0;
926+
field.is_final = (access_flags & field_access_flagst::FINAL) != 0;
927+
field.is_enum = (access_flags & field_access_flagst::ENUM) != 0;
890928

891929
field.descriptor=id2string(pool_entry(descriptor_index).s);
892-
field.is_public=(access_flags&ACC_PUBLIC)!=0;
893-
field.is_protected=(access_flags&ACC_PROTECTED)!=0;
894-
field.is_private=(access_flags&ACC_PRIVATE)!=0;
930+
field.is_public = (access_flags & field_access_flagst::PUBLIC) != 0;
931+
field.is_protected = (access_flags & field_access_flagst::PROTECTED) != 0;
932+
field.is_private = (access_flags & field_access_flagst::PRIVATE) != 0;
895933
const auto flags = (field.is_public ? 1 : 0) +
896934
(field.is_protected?1:0)+
897935
(field.is_private?1:0);
@@ -1578,6 +1616,35 @@ void java_bytecode_parsert::relement_value_pair(
15781616
}
15791617
}
15801618

1619+
/// Represents the bit flag from inner class access and property flags
1620+
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6-300-D.1-D.1
1621+
namespace inner_class_access_flagst
1622+
{
1623+
enum inner_class_access_flagst
1624+
{
1625+
/// Marked or implicitly public in source.
1626+
PUBLIC = 0x0001,
1627+
/// Marked private in source.
1628+
PRIVATE = 0x0002,
1629+
/// Marked protected in source.
1630+
PROTECTED = 0x0004,
1631+
/// Marked or implicitly static in source.
1632+
STATIC = 0x0008,
1633+
/// Marked final in source.
1634+
FINAL = 0x0010,
1635+
/// Was an interface in source.
1636+
INTERFACE = 0x0200,
1637+
/// Marked or implicitly abstract in source.
1638+
ABSTRACT = 0x0400,
1639+
/// Declared synthetic; not present in the source code.
1640+
SYNTHETIC = 0x1000,
1641+
/// Declared as an annotation type.
1642+
ANNOTATION = 0x2000,
1643+
/// Declared as an enum type.
1644+
ENUM = 0x4000,
1645+
};
1646+
}
1647+
15811648
/// Corresponds to the element_value structure
15821649
/// Described in Java 8 specification 4.7.6
15831650
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.7.6
@@ -1619,10 +1686,14 @@ void java_bytecode_parsert::rinner_classes_attribute(
16191686
std::string inner_class_info_name =
16201687
class_infot(pool_entry(inner_class_info_index))
16211688
.get_name(pool_entry_lambda);
1622-
bool is_private = (inner_class_access_flags & ACC_PRIVATE) != 0;
1623-
bool is_public = (inner_class_access_flags & ACC_PUBLIC) != 0;
1624-
bool is_protected = (inner_class_access_flags & ACC_PROTECTED) != 0;
1625-
bool is_static = (inner_class_access_flags & ACC_STATIC) != 0;
1689+
bool is_private =
1690+
(inner_class_access_flags & inner_class_access_flagst::PRIVATE) != 0;
1691+
bool is_public =
1692+
(inner_class_access_flags & inner_class_access_flagst::PUBLIC) != 0;
1693+
bool is_protected =
1694+
(inner_class_access_flags & inner_class_access_flagst::PROTECTED) != 0;
1695+
bool is_static =
1696+
(inner_class_access_flags & inner_class_access_flagst::STATIC) != 0;
16261697

16271698
// If the original parsed class name matches the inner class name,
16281699
// the parsed class is an inner class, so overwrite the parsed class'
@@ -1735,19 +1806,38 @@ void java_bytecode_parsert::rmethods(classt &parsed_class)
17351806
rmethod(parsed_class);
17361807
}
17371808

1738-
#define ACC_PUBLIC 0x0001
1739-
#define ACC_PRIVATE 0x0002
1740-
#define ACC_PROTECTED 0x0004
1741-
#define ACC_STATIC 0x0008
1742-
#define ACC_FINAL 0x0010
1743-
#define ACC_SUPER 0x0020
1744-
#define ACC_VOLATILE 0x0040
1745-
#define ACC_TRANSIENT 0x0080
1746-
#define ACC_INTERFACE 0x0200
1747-
#define ACC_ABSTRACT 0x0400
1748-
#define ACC_SYNTHETIC 0x1000
1749-
#define ACC_ANNOTATION 0x2000
1750-
#define ACC_ENUM 0x4000
1809+
/// Represents the bit flag from Method access and property flags
1810+
/// https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-4.html#jvms-4.6-200-A.1
1811+
namespace method_access_flagst
1812+
{
1813+
enum method_access_flagst
1814+
{
1815+
/// Declared public; may be accessed from outside its package.
1816+
PUBLIC = 0x0001,
1817+
/// Declared private; accessible only within the defining class.
1818+
PRIVATE = 0x0002,
1819+
/// Declared protected; may be accessed within subclasses.
1820+
PROTECTED = 0x0004,
1821+
/// Declared static.
1822+
STATIC = 0x0008,
1823+
/// Declared final; must not be overridden (§5.4.5).
1824+
FINAL = 0x0010,
1825+
/// Declared synchronized; invocation is wrapped by a monitor use.
1826+
SYNCHRONIZED = 0x0020,
1827+
/// A bridge method, generated by the compiler.
1828+
BRIDGE = 0x0040,
1829+
/// Declared with variable number of arguments.
1830+
VARARGS = 0x0080,
1831+
/// Declared native; implemented in a language other than Java.
1832+
NATIVE = 0x0100,
1833+
/// Declared abstract; no implementation is provided.
1834+
ABSTRACT = 0x0400,
1835+
/// Declared strictfp; floating-point mode is FP-strict.
1836+
STRICT = 0x0800,
1837+
/// Declared synthetic; not present in the source code.
1838+
SYNTHETIC = 0x1000
1839+
};
1840+
}
17511841

17521842
void java_bytecode_parsert::rmethod(classt &parsed_class)
17531843
{
@@ -1757,14 +1847,15 @@ void java_bytecode_parsert::rmethod(classt &parsed_class)
17571847
u2 name_index=read_u2();
17581848
u2 descriptor_index=read_u2();
17591849

1760-
method.is_final=(access_flags&ACC_FINAL)!=0;
1761-
method.is_static=(access_flags&ACC_STATIC)!=0;
1762-
method.is_abstract=(access_flags&ACC_ABSTRACT)!=0;
1763-
method.is_public=(access_flags&ACC_PUBLIC)!=0;
1764-
method.is_protected=(access_flags&ACC_PROTECTED)!=0;
1765-
method.is_private=(access_flags&ACC_PRIVATE)!=0;
1766-
method.is_synchronized=(access_flags&ACC_SYNCHRONIZED)!=0;
1767-
method.is_native=(access_flags&ACC_NATIVE)!=0;
1850+
method.is_final = (access_flags & method_access_flagst::FINAL) != 0;
1851+
method.is_static = (access_flags & method_access_flagst::STATIC) != 0;
1852+
method.is_abstract = (access_flags & method_access_flagst::ABSTRACT) != 0;
1853+
method.is_public = (access_flags & method_access_flagst::PUBLIC) != 0;
1854+
method.is_protected = (access_flags & method_access_flagst::PROTECTED) != 0;
1855+
method.is_private = (access_flags & method_access_flagst::PRIVATE) != 0;
1856+
method.is_synchronized =
1857+
(access_flags & method_access_flagst::SYNCHRONIZED) != 0;
1858+
method.is_native = (access_flags & method_access_flagst::NATIVE) != 0;
17681859
method.name=pool_entry(name_index).s;
17691860
method.base_name=pool_entry(name_index).s;
17701861
method.descriptor=id2string(pool_entry(descriptor_index).s);

0 commit comments

Comments
 (0)