Skip to main content

LocalVariableTable

Struct LocalVariableTable 

Source
pub struct LocalVariableTable {
    pub start_pc: u16,
    pub length: u16,
    pub name_index: u16,
    pub descriptor_index: u16,
    pub index: u16,
}
Expand description

Represents an entry in the LocalVariableTable attribute, describing a single local variable.

The LocalVariableTable attribute is an optional attribute in the Code attribute of a method. It is used by debuggers to determine the name and type of a local variable at a given point in the method’s execution.

Note on PC representation: In this implementation, start_pc and length define a range of instruction indices. start_pc is the first instruction index where the variable is in scope, and start_pc + length is the first instruction index where it is no longer in scope. This differs from the raw byte offsets in the class file format.

See the JVMS §4.7.13 for more details.

§Fields

  • start_pc: The instruction index (program counter) from which the local variable is in scope.
  • length: The number of subsequent instruction indices for which the variable remains in scope. The variable is in scope from start_pc to start_pc + length - 1 inclusive.
  • name_index: An index into the constant_pool table. The entry at this index must be a CONSTANT_Utf8_info structure representing the name of the local variable.
  • descriptor_index: An index into the constant_pool table. The entry at this index must be a CONSTANT_Utf8_info structure representing a field descriptor encoding the type of the local variable.
  • index: The local variable’s index in the current frame’s local variable array. If the local variable is of type long or double, it occupies index and index + 1.

§Examples

Basic usage:

use ristretto_classfile::attributes::LocalVariableTable;
use ristretto_classfile::byte_reader::ByteReader;

// Example: A local variable "myVar" of type int, in slot 1,
//          scoped from instruction index 5 for 10 instructions.
let lv_entry = LocalVariableTable {
    start_pc: 5,         // Scope starts at instruction index 5
    length: 10,          // In scope for 10 instructions (indices 5-14)
    name_index: 100,     // CP index for Utf8 "myVar"
    descriptor_index: 101, // CP index for Utf8 "I" (int descriptor)
    index: 1,            // Local variable array slot 1
};

// Serialize the entry
let mut bytes = Vec::new();
lv_entry.to_bytes(&mut bytes)?;

// Deserialize the entry
let mut reader = ByteReader::new(&bytes);
let deserialized_entry = LocalVariableTable::from_bytes(&mut reader)?;

assert_eq!(lv_entry, deserialized_entry);
assert_eq!(lv_entry.to_string(), "start_pc: 5, length: 10, name_index: 100, descriptor_index: 101, index: 1");

Fields§

§start_pc: u16§length: u16§name_index: u16§descriptor_index: u16§index: u16

Implementations§

Source§

impl LocalVariableTable

Source

pub fn from_bytes(bytes: &mut ByteReader<'_>) -> Result<LocalVariableTable>

Deserializes a LocalVariableTable entry from a byte stream.

Reads start_pc, length, name_index, descriptor_index, and index from the stream. Note that start_pc and length are read as raw PC values/lengths (typically byte offsets in a class file) and may need further mapping to logical instruction indices/counts depending on the context.

§Errors

Returns an error if reading from the byte stream fails.

§Examples
use ristretto_classfile::attributes::LocalVariableTable;
use ristretto_classfile::byte_reader::ByteReader;

// Byte data for a LocalVariableTable entry:
// start_pc=10, length=50, name_idx=1, desc_idx=2, index=3
let data = vec![0, 10, 0, 50, 0, 1, 0, 2, 0, 3];
let mut reader = ByteReader::new(&data);

let lv_entry = LocalVariableTable::from_bytes(&mut reader)?;

assert_eq!(lv_entry.start_pc, 10);
assert_eq!(lv_entry.length, 50);
assert_eq!(lv_entry.name_index, 1);
assert_eq!(lv_entry.descriptor_index, 2);
assert_eq!(lv_entry.index, 3);
Source

pub fn to_bytes(&self, bytes: &mut Vec<u8>) -> Result<()>

Serializes the LocalVariableTable entry to a byte vector.

Writes start_pc, length, name_index, descriptor_index, and index to the vector. Note that start_pc and length are written directly; if they represent logical instruction indices/counts, they must be converted to byte offsets/lengths before serialization in the context of a Code attribute.

§Errors

Returns an error if writing to the byte vector fails.

§Examples
use ristretto_classfile::attributes::LocalVariableTable;

let lv_entry = LocalVariableTable {
    start_pc: 0,
    length: 100,
    name_index: 5,
    descriptor_index: 6,
    index: 0,
};

let mut bytes = Vec::new();
lv_entry.to_bytes(&mut bytes)?;

// Expected: start_pc(0), length(100), name(5), desc(6), index(0)
assert_eq!(bytes, vec![0, 0, 0, 100, 0, 5, 0, 6, 0, 0]);

Trait Implementations§

Source§

impl Clone for LocalVariableTable

Source§

fn clone(&self) -> LocalVariableTable

Returns a duplicate of the value. Read more
1.0.0 (const: unstable) · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl Debug for LocalVariableTable

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl Display for LocalVariableTable

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the LocalVariableTable entry as a human-readable string.

This implementation provides a simple comma-separated representation of all fields in the LocalVariableTable entry, making it useful for debugging and logging.

§Examples
use ristretto_classfile::attributes::LocalVariableTable;

let lv_entry = LocalVariableTable {
    start_pc: 5,
    length: 10,
    name_index: 15,
    descriptor_index: 20,
    index: 2,
};

// Using to_string() to get the formatted string
let output = lv_entry.to_string();
assert_eq!(
    output,
    "start_pc: 5, length: 10, name_index: 15, descriptor_index: 20, index: 2"
);
Source§

impl Eq for LocalVariableTable

Source§

impl PartialEq for LocalVariableTable

Source§

fn eq(&self, other: &LocalVariableTable) -> bool

Equality operator ==. Read more
1.0.0 (const: unstable) · Source§

fn ne(&self, other: &Rhs) -> bool

Inequality operator !=. Read more
Source§

impl StructuralPartialEq for LocalVariableTable

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
where ST: ?Sized, DT: ?Sized,

Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<Q, K> Equivalent<K> for Q
where Q: Eq + ?Sized, K: Borrow<Q> + ?Sized,

Source§

fn equivalent(&self, key: &K) -> bool

Compare self to key and return true if they are equal.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> Read<Exclusive, BecauseExclusive> for T
where T: ?Sized,

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.