8#ifndef RPNX_CORTADO_BYTECODE_HPP
9#define RPNX_CORTADO_BYTECODE_HPP
57 enum class newarray_type : std::uint8_t {
boolean = 4, character = 5, floating_point = 6, double_precision = 7,
byte = 8, short_integer = 9, integer = 10, long_integer = 11 };
60 enum class opcode : std::uint8_t { nop = 0x00, aconst_null = 0x01, iconst_m1 = 0x02, iconst_0 = 0x03, iconst_1 = 0x04, iconst_2 = 0x05, iconst_3 = 0x06, iconst_4 = 0x07, iconst_5 = 0x08, lconst_0 = 0x09, lconst_1 = 0x0A, fconst_0 = 0x0B, fconst_1 = 0x0C, fconst_2 = 0x0D, dconst_0 = 0x0E, dconst_1 = 0x0F, bipush = 0x10, sipush = 0x11, ldc = 0x12, ldc_w = 0x13, ldc2_w = 0x14, iload = 0x15, lload = 0x16, fload = 0x17, dload = 0x18, aload = 0x19, iload_0 = 0x1A, iload_1 = 0x1B, iload_2 = 0x1C, iload_3 = 0x1D, lload_0 = 0x1E, lload_1 = 0x1F, lload_2 = 0x20, lload_3 = 0x21, fload_0 = 0x22, fload_1 = 0x23, fload_2 = 0x24, fload_3 = 0x25, dload_0 = 0x26, dload_1 = 0x27, dload_2 = 0x28, dload_3 = 0x29, aload_0 = 0x2A, aload_1 = 0x2B, aload_2 = 0x2C, aload_3 = 0x2D, iaload = 0x2E, laload = 0x2F, faload = 0x30, daload = 0x31, aaload = 0x32, baload = 0x33, caload = 0x34, saload = 0x35, istore = 0x36, lstore = 0x37, fstore = 0x38, dstore = 0x39, astore = 0x3A, istore_0 = 0x3B, istore_1 = 0x3C, istore_2 = 0x3D, istore_3 = 0x3E, lstore_0 = 0x3F, lstore_1 = 0x40, lstore_2 = 0x41, lstore_3 = 0x42, fstore_0 = 0x43, fstore_1 = 0x44, fstore_2 = 0x45, fstore_3 = 0x46, dstore_0 = 0x47, dstore_1 = 0x48, dstore_2 = 0x49, dstore_3 = 0x4A, astore_0 = 0x4B, astore_1 = 0x4C, astore_2 = 0x4D, astore_3 = 0x4E, iastore = 0x4F, lastore = 0x50, fastore = 0x51, dastore = 0x52, aastore = 0x53, bastore = 0x54, castore = 0x55, sastore = 0x56, pop = 0x57, pop2 = 0x58, dup = 0x59, dup_x1 = 0x5A, dup_x2 = 0x5B, dup2 = 0x5C, dup2_x1 = 0x5D, dup2_x2 = 0x5E, swap = 0x5F, iadd = 0x60, ladd = 0x61, fadd = 0x62, dadd = 0x63, isub = 0x64, lsub = 0x65, fsub = 0x66, dsub = 0x67, imul = 0x68, lmul = 0x69, fmul = 0x6A, dmul = 0x6B, idiv = 0x6C, ldiv = 0x6D, fdiv = 0x6E, ddiv = 0x6F, irem = 0x70, lrem = 0x71, frem = 0x72, drem = 0x73, ineg = 0x74, lneg = 0x75, fneg = 0x76, dneg = 0x77, ishl = 0x78, lshl = 0x79, ishr = 0x7A, lshr = 0x7B, iushr = 0x7C, lushr = 0x7D, iand = 0x7E, land = 0x7F, ior = 0x80, lor = 0x81, ixor = 0x82, lxor = 0x83, iinc = 0x84, i2l = 0x85, i2f = 0x86, i2d = 0x87, l2i = 0x88, l2f = 0x89, l2d = 0x8A, f2i = 0x8B, f2l = 0x8C, f2d = 0x8D, d2i = 0x8E, d2l = 0x8F, d2f = 0x90, i2b = 0x91, i2c = 0x92, i2s = 0x93, lcmp = 0x94, fcmpl = 0x95, fcmpg = 0x96, dcmpl = 0x97, dcmpg = 0x98, ifeq = 0x99, ifne = 0x9A, iflt = 0x9B, ifge = 0x9C, ifgt = 0x9D, ifle = 0x9E, if_icmpeq = 0x9F, if_icmpne = 0xA0, if_icmplt = 0xA1, if_icmpge = 0xA2, if_icmpgt = 0xA3, if_icmple = 0xA4, if_acmpeq = 0xA5, if_acmpne = 0xA6, goto_ = 0xA7, jsr = 0xA8, ret = 0xA9, tableswitch = 0xAA, lookupswitch = 0xAB, ireturn = 0xAC, lreturn = 0xAD, freturn = 0xAE, dreturn = 0xAF, areturn = 0xB0, return_ = 0xB1, getstatic = 0xB2, putstatic = 0xB3, getfield = 0xB4, putfield = 0xB5, invokevirtual = 0xB6, invokespecial = 0xB7, invokestatic = 0xB8, invokeinterface = 0xB9, invokedynamic = 0xBA, new_ = 0xBB, newarray = 0xBC, anewarray = 0xBD, arraylength = 0xBE, athrow = 0xBF, checkcast = 0xC0, instanceof_ = 0xC1, monitorenter = 0xC2, monitorexit = 0xC3, wide = 0xC4, multianewarray = 0xC5, ifnull = 0xC6, ifnonnull = 0xC7, goto_w = 0xC8, jsr_w = 0xC9, breakpoint = 0xCA, impdep1 = 0xFE, impdep2 = 0xFF };
63 template < opcode Operation >
66 static constexpr opcode operation = Operation;
71 template < opcode Operation >
74 static constexpr opcode operation = Operation;
80 template < opcode Operation >
83 static constexpr opcode operation = Operation;
89 template < opcode Operation >
92 static constexpr opcode operation = Operation;
98 template < opcode Operation >
101 static constexpr opcode operation = Operation;
107 template < opcode Operation >
110 static constexpr opcode operation = Operation;
116 template < opcode Operation >
119 static constexpr opcode operation = Operation;
125 template < opcode Operation >
128 static constexpr opcode operation = Operation;
136 static constexpr opcode operation = opcode::iinc;
143 template < opcode ModifiedOperation >
146 static constexpr opcode modified_operation = ModifiedOperation;
160 using wide_operand = std::variant< wide_local_instruction< opcode::iload >,
wide_local_instruction< opcode::lload >,
wide_local_instruction< opcode::fload >,
wide_local_instruction< opcode::dload >,
wide_local_instruction< opcode::aload >,
wide_local_instruction< opcode::istore >,
wide_local_instruction< opcode::lstore >,
wide_local_instruction< opcode::fstore >,
wide_local_instruction< opcode::dstore >,
wide_local_instruction< opcode::astore >,
wide_local_instruction< opcode::ret >,
wide_iinc_instruction >;
165 static constexpr opcode operation = opcode::wide;
181 static constexpr opcode operation = opcode::tableswitch;
192 static constexpr opcode operation = opcode::lookupswitch;
195 std::vector< lookup_switch_pair >
pairs;
202 static constexpr opcode operation = opcode::invokeinterface;
212 static constexpr opcode operation = opcode::invokedynamic;
221 static constexpr opcode operation = opcode::newarray;
229 static constexpr opcode operation = opcode::multianewarray;
236 using instruction = std::variant< simple_instruction< opcode::nop >,
simple_instruction< opcode::aconst_null >,
simple_instruction< opcode::iconst_m1 >,
simple_instruction< opcode::iconst_0 >,
simple_instruction< opcode::iconst_1 >,
simple_instruction< opcode::iconst_2 >,
simple_instruction< opcode::iconst_3 >,
simple_instruction< opcode::iconst_4 >,
simple_instruction< opcode::iconst_5 >,
simple_instruction< opcode::lconst_0 >,
simple_instruction< opcode::lconst_1 >,
simple_instruction< opcode::fconst_0 >,
simple_instruction< opcode::fconst_1 >,
simple_instruction< opcode::fconst_2 >,
simple_instruction< opcode::dconst_0 >,
simple_instruction< opcode::dconst_1 >,
signed_byte_instruction< opcode::bipush >,
signed_short_instruction< opcode::sipush >,
constant_pool_index8_instruction< opcode::ldc >,
constant_pool_index16_instruction< opcode::ldc_w >,
constant_pool_index16_instruction< opcode::ldc2_w >,
local_instruction< opcode::iload >,
local_instruction< opcode::lload >,
local_instruction< opcode::fload >,
local_instruction< opcode::dload >,
local_instruction< opcode::aload >,
simple_instruction< opcode::iload_0 >,
simple_instruction< opcode::iload_1 >,
simple_instruction< opcode::iload_2 >,
simple_instruction< opcode::iload_3 >,
simple_instruction< opcode::lload_0 >,
simple_instruction< opcode::lload_1 >,
simple_instruction< opcode::lload_2 >,
simple_instruction< opcode::lload_3 >,
simple_instruction< opcode::fload_0 >,
simple_instruction< opcode::fload_1 >,
simple_instruction< opcode::fload_2 >,
simple_instruction< opcode::fload_3 >,
simple_instruction< opcode::dload_0 >,
simple_instruction< opcode::dload_1 >,
simple_instruction< opcode::dload_2 >,
simple_instruction< opcode::dload_3 >,
simple_instruction< opcode::aload_0 >,
simple_instruction< opcode::aload_1 >,
simple_instruction< opcode::aload_2 >,
simple_instruction< opcode::aload_3 >,
simple_instruction< opcode::iaload >,
simple_instruction< opcode::laload >,
simple_instruction< opcode::faload >,
simple_instruction< opcode::daload >,
simple_instruction< opcode::aaload >,
simple_instruction< opcode::baload >,
simple_instruction< opcode::caload >,
simple_instruction< opcode::saload >,
local_instruction< opcode::istore >,
local_instruction< opcode::lstore >,
local_instruction< opcode::fstore >,
local_instruction< opcode::dstore >,
local_instruction< opcode::astore >,
simple_instruction< opcode::istore_0 >,
simple_instruction< opcode::istore_1 >,
simple_instruction< opcode::istore_2 >,
simple_instruction< opcode::istore_3 >,
simple_instruction< opcode::lstore_0 >,
simple_instruction< opcode::lstore_1 >,
simple_instruction< opcode::lstore_2 >,
simple_instruction< opcode::lstore_3 >,
simple_instruction< opcode::fstore_0 >,
simple_instruction< opcode::fstore_1 >,
simple_instruction< opcode::fstore_2 >,
simple_instruction< opcode::fstore_3 >,
simple_instruction< opcode::dstore_0 >,
simple_instruction< opcode::dstore_1 >,
simple_instruction< opcode::dstore_2 >,
simple_instruction< opcode::dstore_3 >,
simple_instruction< opcode::astore_0 >,
simple_instruction< opcode::astore_1 >,
simple_instruction< opcode::astore_2 >,
simple_instruction< opcode::astore_3 >,
simple_instruction< opcode::iastore >,
simple_instruction< opcode::lastore >,
simple_instruction< opcode::fastore >,
simple_instruction< opcode::dastore >,
simple_instruction< opcode::aastore >,
simple_instruction< opcode::bastore >,
simple_instruction< opcode::castore >,
simple_instruction< opcode::sastore >,
simple_instruction< opcode::pop >,
simple_instruction< opcode::pop2 >,
simple_instruction< opcode::dup >,
simple_instruction< opcode::dup_x1 >,
simple_instruction< opcode::dup_x2 >,
simple_instruction< opcode::dup2 >,
simple_instruction< opcode::dup2_x1 >,
simple_instruction< opcode::dup2_x2 >,
simple_instruction< opcode::swap >,
simple_instruction< opcode::iadd >,
simple_instruction< opcode::ladd >,
simple_instruction< opcode::fadd >,
simple_instruction< opcode::dadd >,
simple_instruction< opcode::isub >,
simple_instruction< opcode::lsub >,
simple_instruction< opcode::fsub >,
simple_instruction< opcode::dsub >,
simple_instruction< opcode::imul >,
simple_instruction< opcode::lmul >,
simple_instruction< opcode::fmul >,
simple_instruction< opcode::dmul >,
simple_instruction< opcode::idiv >,
simple_instruction< opcode::ldiv >,
simple_instruction< opcode::fdiv >,
simple_instruction< opcode::ddiv >,
simple_instruction< opcode::irem >,
simple_instruction< opcode::lrem >,
simple_instruction< opcode::frem >,
simple_instruction< opcode::drem >,
simple_instruction< opcode::ineg >,
simple_instruction< opcode::lneg >,
simple_instruction< opcode::fneg >,
simple_instruction< opcode::dneg >,
simple_instruction< opcode::ishl >,
simple_instruction< opcode::lshl >,
simple_instruction< opcode::ishr >,
simple_instruction< opcode::lshr >,
simple_instruction< opcode::iushr >,
simple_instruction< opcode::lushr >,
simple_instruction< opcode::iand >,
simple_instruction< opcode::land >,
simple_instruction< opcode::ior >,
simple_instruction< opcode::lor >,
simple_instruction< opcode::ixor >,
simple_instruction< opcode::lxor >,
iinc_instruction,
simple_instruction< opcode::i2l >,
simple_instruction< opcode::i2f >,
simple_instruction< opcode::i2d >,
simple_instruction< opcode::l2i >,
simple_instruction< opcode::l2f >,
simple_instruction< opcode::l2d >,
simple_instruction< opcode::f2i >,
simple_instruction< opcode::f2l >,
simple_instruction< opcode::f2d >,
simple_instruction< opcode::d2i >,
simple_instruction< opcode::d2l >,
simple_instruction< opcode::d2f >,
simple_instruction< opcode::i2b >,
simple_instruction< opcode::i2c >,
simple_instruction< opcode::i2s >,
simple_instruction< opcode::lcmp >,
simple_instruction< opcode::fcmpl >,
simple_instruction< opcode::fcmpg >,
simple_instruction< opcode::dcmpl >,
simple_instruction< opcode::dcmpg >,
branch16_instruction< opcode::ifeq >,
branch16_instruction< opcode::ifne >,
branch16_instruction< opcode::iflt >,
branch16_instruction< opcode::ifge >,
branch16_instruction< opcode::ifgt >,
branch16_instruction< opcode::ifle >,
branch16_instruction< opcode::if_icmpeq >,
branch16_instruction< opcode::if_icmpne >,
branch16_instruction< opcode::if_icmplt >,
branch16_instruction< opcode::if_icmpge >,
branch16_instruction< opcode::if_icmpgt >,
branch16_instruction< opcode::if_icmple >,
branch16_instruction< opcode::if_acmpeq >,
branch16_instruction< opcode::if_acmpne >,
branch16_instruction< opcode::goto_ >,
branch16_instruction< opcode::jsr >,
local_instruction< opcode::ret >,
tableswitch_instruction,
lookupswitch_instruction,
simple_instruction< opcode::ireturn >,
simple_instruction< opcode::lreturn >,
simple_instruction< opcode::freturn >,
simple_instruction< opcode::dreturn >,
simple_instruction< opcode::areturn >,
simple_instruction< opcode::return_ >,
constant_pool_index16_instruction< opcode::getstatic >,
constant_pool_index16_instruction< opcode::putstatic >,
constant_pool_index16_instruction< opcode::getfield >,
constant_pool_index16_instruction< opcode::putfield >,
constant_pool_index16_instruction< opcode::invokevirtual >,
constant_pool_index16_instruction< opcode::invokespecial >,
constant_pool_index16_instruction< opcode::invokestatic >,
invokeinterface_instruction,
invokedynamic_instruction,
constant_pool_index16_instruction< opcode::new_ >,
newarray_instruction,
constant_pool_index16_instruction< opcode::anewarray >,
simple_instruction< opcode::arraylength >,
simple_instruction< opcode::athrow >,
constant_pool_index16_instruction< opcode::checkcast >,
constant_pool_index16_instruction< opcode::instanceof_ >,
simple_instruction< opcode::monitorenter >,
simple_instruction< opcode::monitorexit >,
wide_instruction,
multianewarray_instruction,
branch16_instruction< opcode::ifnull >,
branch16_instruction< opcode::ifnonnull >,
branch32_instruction< opcode::goto_w >,
branch32_instruction< opcode::jsr_w >,
simple_instruction< opcode::breakpoint >,
simple_instruction< opcode::impdep1 >,
simple_instruction< opcode::impdep2 > >;
238 namespace bytecode_model_detail
240 template < std::size_t... Indexes >
241 [[nodiscard]]
consteval bool has_complete_unique_opcode_coverage(std::index_sequence< Indexes... >)
243 std::array< bool, 256 > seen{};
245 auto record = [&](
opcode operation)
247 std::size_t
const value =
static_cast< std::uint8_t
>(operation);
254 (record(std::variant_alternative_t< Indexes, instruction >::operation), ...);
259 for (std::size_t value = 0; value <= static_cast< std::uint8_t >(opcode::breakpoint); ++value)
266 return seen[
static_cast< std::uint8_t
>(opcode::impdep1)] && seen[
static_cast< std::uint8_t
>(opcode::impdep2)];
270 static_assert(std::variant_size_v< instruction > == 205,
"the instruction variant must contain every defined and reserved JVM opcode exactly once");
271 static_assert(bytecode_model_detail::has_complete_unique_opcode_coverage(std::make_index_sequence< std::variant_size_v< instruction > >{}),
"the instruction variant has an omitted or duplicate JVM opcode");
279 template <
typename Visitor >
282 using visitor_type = std::remove_reference_t< Visitor >;
283 using callback = void (*)(visitor_type&);
284 static constexpr std::array< callback, 256 > callbacks = []< std::size_t... Indexes >(std::index_sequence< Indexes... >)
286 std::array< callback, 256 > result{};
287 ((result[
static_cast< std::uint8_t
>(std::variant_alternative_t< Indexes, instruction >::operation)] = [](visitor_type& value)
288 { value(std::type_identity< std::variant_alternative_t< Indexes, instruction > >{}); }),
291 }(std::make_index_sequence< std::variant_size_v< instruction > >{});
293 callback
const selected = callbacks[
static_cast< std::uint8_t
>(operation)];
294 if (selected ==
nullptr)
317 using code_body = std::variant< instruction_sequence, raw_code >;
370 template <
typename OutputIt >
374 for (std::byte
const byte : bytes)
391 template <
typename OutputIt >
395 for (std::byte
const byte : bytes)
399 throw std::length_error(
"output range is too small for the JVM code array");
416 template < std::forward_iterator InputIt, std::sentinel_for< InputIt > Sentinel >
419 std::vector< std::byte > bytes;
420 for (InputIt cursor = input; cursor != end; ++cursor)
422 bytes.push_back(
static_cast< std::byte
>(*cursor));
Exception types used by parsing, validation, and assembly APIs.
JVM class-file, bytecode, validation, generation, and JAR APIs.
processing_mode
Controls whether invalid-but-preservable tool input is accepted.
std::variant< instruction_sequence, raw_code > code_body
Either a decoded instruction sequence or an exact raw tooling payload.
std::variant< simple_instruction< opcode::nop >, simple_instruction< opcode::aconst_null >, simple_instruction< opcode::iconst_m1 >, simple_instruction< opcode::iconst_0 >, simple_instruction< opcode::iconst_1 >, simple_instruction< opcode::iconst_2 >, simple_instruction< opcode::iconst_3 >, simple_instruction< opcode::iconst_4 >, simple_instruction< opcode::iconst_5 >, simple_instruction< opcode::lconst_0 >, simple_instruction< opcode::lconst_1 >, simple_instruction< opcode::fconst_0 >, simple_instruction< opcode::fconst_1 >, simple_instruction< opcode::fconst_2 >, simple_instruction< opcode::dconst_0 >, simple_instruction< opcode::dconst_1 >, signed_byte_instruction< opcode::bipush >, signed_short_instruction< opcode::sipush >, constant_pool_index8_instruction< opcode::ldc >, constant_pool_index16_instruction< opcode::ldc_w >, constant_pool_index16_instruction< opcode::ldc2_w >, local_instruction< opcode::iload >, local_instruction< opcode::lload >, local_instruction< opcode::fload >, local_instruction< opcode::dload >, local_instruction< opcode::aload >, simple_instruction< opcode::iload_0 >, simple_instruction< opcode::iload_1 >, simple_instruction< opcode::iload_2 >, simple_instruction< opcode::iload_3 >, simple_instruction< opcode::lload_0 >, simple_instruction< opcode::lload_1 >, simple_instruction< opcode::lload_2 >, simple_instruction< opcode::lload_3 >, simple_instruction< opcode::fload_0 >, simple_instruction< opcode::fload_1 >, simple_instruction< opcode::fload_2 >, simple_instruction< opcode::fload_3 >, simple_instruction< opcode::dload_0 >, simple_instruction< opcode::dload_1 >, simple_instruction< opcode::dload_2 >, simple_instruction< opcode::dload_3 >, simple_instruction< opcode::aload_0 >, simple_instruction< opcode::aload_1 >, simple_instruction< opcode::aload_2 >, simple_instruction< opcode::aload_3 >, simple_instruction< opcode::iaload >, simple_instruction< opcode::laload >, simple_instruction< opcode::faload >, simple_instruction< opcode::daload >, simple_instruction< opcode::aaload >, simple_instruction< opcode::baload >, simple_instruction< opcode::caload >, simple_instruction< opcode::saload >, local_instruction< opcode::istore >, local_instruction< opcode::lstore >, local_instruction< opcode::fstore >, local_instruction< opcode::dstore >, local_instruction< opcode::astore >, simple_instruction< opcode::istore_0 >, simple_instruction< opcode::istore_1 >, simple_instruction< opcode::istore_2 >, simple_instruction< opcode::istore_3 >, simple_instruction< opcode::lstore_0 >, simple_instruction< opcode::lstore_1 >, simple_instruction< opcode::lstore_2 >, simple_instruction< opcode::lstore_3 >, simple_instruction< opcode::fstore_0 >, simple_instruction< opcode::fstore_1 >, simple_instruction< opcode::fstore_2 >, simple_instruction< opcode::fstore_3 >, simple_instruction< opcode::dstore_0 >, simple_instruction< opcode::dstore_1 >, simple_instruction< opcode::dstore_2 >, simple_instruction< opcode::dstore_3 >, simple_instruction< opcode::astore_0 >, simple_instruction< opcode::astore_1 >, simple_instruction< opcode::astore_2 >, simple_instruction< opcode::astore_3 >, simple_instruction< opcode::iastore >, simple_instruction< opcode::lastore >, simple_instruction< opcode::fastore >, simple_instruction< opcode::dastore >, simple_instruction< opcode::aastore >, simple_instruction< opcode::bastore >, simple_instruction< opcode::castore >, simple_instruction< opcode::sastore >, simple_instruction< opcode::pop >, simple_instruction< opcode::pop2 >, simple_instruction< opcode::dup >, simple_instruction< opcode::dup_x1 >, simple_instruction< opcode::dup_x2 >, simple_instruction< opcode::dup2 >, simple_instruction< opcode::dup2_x1 >, simple_instruction< opcode::dup2_x2 >, simple_instruction< opcode::swap >, simple_instruction< opcode::iadd >, simple_instruction< opcode::ladd >, simple_instruction< opcode::fadd >, simple_instruction< opcode::dadd >, simple_instruction< opcode::isub >, simple_instruction< opcode::lsub >, simple_instruction< opcode::fsub >, simple_instruction< opcode::dsub >, simple_instruction< opcode::imul >, simple_instruction< opcode::lmul >, simple_instruction< opcode::fmul >, simple_instruction< opcode::dmul >, simple_instruction< opcode::idiv >, simple_instruction< opcode::ldiv >, simple_instruction< opcode::fdiv >, simple_instruction< opcode::ddiv >, simple_instruction< opcode::irem >, simple_instruction< opcode::lrem >, simple_instruction< opcode::frem >, simple_instruction< opcode::drem >, simple_instruction< opcode::ineg >, simple_instruction< opcode::lneg >, simple_instruction< opcode::fneg >, simple_instruction< opcode::dneg >, simple_instruction< opcode::ishl >, simple_instruction< opcode::lshl >, simple_instruction< opcode::ishr >, simple_instruction< opcode::lshr >, simple_instruction< opcode::iushr >, simple_instruction< opcode::lushr >, simple_instruction< opcode::iand >, simple_instruction< opcode::land >, simple_instruction< opcode::ior >, simple_instruction< opcode::lor >, simple_instruction< opcode::ixor >, simple_instruction< opcode::lxor >, iinc_instruction, simple_instruction< opcode::i2l >, simple_instruction< opcode::i2f >, simple_instruction< opcode::i2d >, simple_instruction< opcode::l2i >, simple_instruction< opcode::l2f >, simple_instruction< opcode::l2d >, simple_instruction< opcode::f2i >, simple_instruction< opcode::f2l >, simple_instruction< opcode::f2d >, simple_instruction< opcode::d2i >, simple_instruction< opcode::d2l >, simple_instruction< opcode::d2f >, simple_instruction< opcode::i2b >, simple_instruction< opcode::i2c >, simple_instruction< opcode::i2s >, simple_instruction< opcode::lcmp >, simple_instruction< opcode::fcmpl >, simple_instruction< opcode::fcmpg >, simple_instruction< opcode::dcmpl >, simple_instruction< opcode::dcmpg >, branch16_instruction< opcode::ifeq >, branch16_instruction< opcode::ifne >, branch16_instruction< opcode::iflt >, branch16_instruction< opcode::ifge >, branch16_instruction< opcode::ifgt >, branch16_instruction< opcode::ifle >, branch16_instruction< opcode::if_icmpeq >, branch16_instruction< opcode::if_icmpne >, branch16_instruction< opcode::if_icmplt >, branch16_instruction< opcode::if_icmpge >, branch16_instruction< opcode::if_icmpgt >, branch16_instruction< opcode::if_icmple >, branch16_instruction< opcode::if_acmpeq >, branch16_instruction< opcode::if_acmpne >, branch16_instruction< opcode::goto_ >, branch16_instruction< opcode::jsr >, local_instruction< opcode::ret >, tableswitch_instruction, lookupswitch_instruction, simple_instruction< opcode::ireturn >, simple_instruction< opcode::lreturn >, simple_instruction< opcode::freturn >, simple_instruction< opcode::dreturn >, simple_instruction< opcode::areturn >, simple_instruction< opcode::return_ >, constant_pool_index16_instruction< opcode::getstatic >, constant_pool_index16_instruction< opcode::putstatic >, constant_pool_index16_instruction< opcode::getfield >, constant_pool_index16_instruction< opcode::putfield >, constant_pool_index16_instruction< opcode::invokevirtual >, constant_pool_index16_instruction< opcode::invokespecial >, constant_pool_index16_instruction< opcode::invokestatic >, invokeinterface_instruction, invokedynamic_instruction, constant_pool_index16_instruction< opcode::new_ >, newarray_instruction, constant_pool_index16_instruction< opcode::anewarray >, simple_instruction< opcode::arraylength >, simple_instruction< opcode::athrow >, constant_pool_index16_instruction< opcode::checkcast >, constant_pool_index16_instruction< opcode::instanceof_ >, simple_instruction< opcode::monitorenter >, simple_instruction< opcode::monitorexit >, wide_instruction, multianewarray_instruction, branch16_instruction< opcode::ifnull >, branch16_instruction< opcode::ifnonnull >, branch32_instruction< opcode::goto_w >, branch32_instruction< opcode::jsr_w >, simple_instruction< opcode::breakpoint >, simple_instruction< opcode::impdep1 >, simple_instruction< opcode::impdep2 > > instruction
Every exact JVM instruction encoding supported by Java SE 26.
std::size_t instruction_size(instruction const &value, code_offset offset)
Returns the exact encoded size of an instruction at the supplied byte offset.
bool visit_instruction_type(opcode operation, Visitor &&visitor)
Invokes a visitor with the instruction type associated with a runtime opcode.
std::variant< wide_local_instruction< opcode::iload >, wide_local_instruction< opcode::lload >, wide_local_instruction< opcode::fload >, wide_local_instruction< opcode::dload >, wide_local_instruction< opcode::aload >, wide_local_instruction< opcode::istore >, wide_local_instruction< opcode::lstore >, wide_local_instruction< opcode::fstore >, wide_local_instruction< opcode::dstore >, wide_local_instruction< opcode::astore >, wide_local_instruction< opcode::ret >, wide_iinc_instruction > wide_operand
Exact operand of a wide-prefixed instruction.
opcode instruction_opcode(instruction const &value) noexcept
Returns the opcode of a structured instruction.
opcode
Every defined Java SE 26 opcode, plus the three permanently reserved opcodes.
code_body deserialize_instructions(std::span< std::byte const > bytes, bytecode_read_options const &options={})
Decodes an entire JVM code array.
newarray_type
Primitive array types accepted by the newarray instruction.
auto serialize_iter(code_body const &value, OutputIt output, bytecode_write_options const &options={}) -> OutputIt
Serial4-style bytecode output-iterator interface.
std::vector< std::byte > serialize_instructions(code_body const &value, bytecode_write_options const &options={})
Encodes an entire JVM code array.
auto deserialize_iter(code_body &value, InputIt input, Sentinel end, bytecode_read_options const &options={}) -> InputIt
Serial4-style bytecode forward-iterator interface.
A two-byte branch instruction.
branch_displacement16 displacement
Target displacement relative to this instruction's opcode.
A four-byte branch instruction.
branch_displacement32 displacement
Target displacement relative to this instruction's opcode.
A signed 16-bit branch displacement relative to an instruction opcode.
std::int16_t value
Signed bytes from the branch opcode to its target opcode.
A signed 32-bit branch displacement relative to an instruction opcode.
std::int32_t value
Signed bytes from the branch opcode to its target opcode.
Resource and strictness controls for bytecode decoding.
std::size_t maximum_code_length
Maximum bytes accepted, additionally capped by the JVM limit.
processing_mode mode
Strict rejection or raw-code tooling fallback.
Strictness controls for bytecode encoding.
processing_mode mode
Strict rejection or exact raw/reserved tooling output.
A byte offset within the code array of a Code attribute.
std::uint32_t value
Byte offset from the first opcode in the enclosing code array.
A two-byte constant-pool-index instruction.
constant_pool_index index
Two-byte logical constant-pool index.
A one-byte constant-pool-index instruction.
std::uint8_t index
Nonzero one-byte constant-pool index.
A type-safe index into a JVM constant pool.
The compact iinc instruction.
std::int8_t amount
Signed increment.
std::uint8_t index
Local int slot to update.
An owning sequence of exactly decoded instruction encodings.
std::vector< instruction > instructions
Instructions in increasing byte-offset order.
The invokedynamic instruction, including its reserved field.
constant_pool_index index
Index of a CONSTANT_InvokeDynamic entry.
std::uint16_t reserved
Format-reserved two-byte field; zero in valid class files.
The invokeinterface instruction, including its reserved byte.
std::uint8_t reserved
Format-reserved byte; zero in valid class files.
std::uint8_t count
Nonzero argument slot count, including the receiver.
constant_pool_index index
Index of a CONSTANT_InterfaceMethodref entry.
A one-byte local-variable-index instruction.
std::uint8_t index
Zero-based local-variable-array slot.
A JVM local-variable-array index.
std::uint16_t value
Zero-based local-variable-array slot.
One match/target pair in a lookupswitch instruction.
std::int32_t match
Lookup key; pairs must be strictly increasing in strict mode.
branch_displacement32 displacement
Branch target for this key, relative to the switch opcode.
An exact lookupswitch instruction, including alignment bytes.
std::vector< lookup_switch_pair > pairs
Strictly increasing match/target pairs.
std::vector< std::byte > padding
Exact zero-to-three bytes aligning the default operand to four bytes.
branch_displacement32 default_displacement
Target used when no pair matches.
The multianewarray instruction.
std::uint8_t dimensions
Nonzero number of leading array dimensions to allocate.
constant_pool_index index
Index of a CONSTANT_Class containing an array descriptor.
The newarray instruction.
newarray_type element_type
Primitive component kind selected by the atype operand.
An undecoded Code body retained by tooling mode.
std::vector< std::byte > bytes
Complete, byte-for-byte code array retained after decoding became unsafe.
A signed one-byte immediate instruction.
std::int8_t value
Immediate operand in host signed representation.
A signed two-byte immediate instruction.
std::int16_t value
Immediate operand in host signed representation.
An instruction whose encoding contains only its opcode.
An exact tableswitch instruction, including alignment bytes.
std::vector< std::byte > padding
Exact zero-to-three bytes aligning the default operand to four bytes.
std::int32_t low
Lowest table key; the highest key is derived from the target count.
std::vector< branch_displacement32 > displacements
Consecutive targets beginning at low; never empty in strict mode.
branch_displacement32 default_displacement
Target used when the key is outside the table.
The wide iinc form following the wide prefix.
local_variable_index index
Two-byte local int slot to update.
std::int16_t amount
Signed two-byte increment.
A complete wide-prefixed instruction.
wide_operand operand
Modified local instruction encoded after the wide prefix.
A wide local-variable instruction following the wide prefix.
local_variable_index index
Two-byte local-variable-array slot.
Fundamental class-file, constant-pool, and JAR value types.