Class Descriptor – Metadatos de Clases y Objetos
Archivo: src/class_descriptor.rs
Define las estructuras de datos que describen la forma (shape) y el comportamiento de las clases de Forja en tiempo de ejecución. La VM utiliza estos descriptores para crear instancias, resolver atributos y métodos, y gestionar la herencia.
Shape — Forma de los Objetos
Estructura Shape
pub struct Shape {
pub campo_a_indice: HashMap<SymId, usize>,
pub indice_a_campo: Vec<SymId>,
} Shape define la estructura de campos compartida por todas las instancias de una misma clase. Esto permite que los objetos sean livianos: cada instancia solo almacena valores; la información de qué campos existen y en qué orden está centralizada en el Shape.
Métodos de Shape
| Método | Descripción |
|---|---|
pub fn new() -> Self | Crea un nuevo shape vacío, sin campos. |
pub fn add_campo(&mut self, nombre: SymId) -> usize | Agrega un nuevo campo al shape. Retorna el índice numérico asignado al campo. Si se vuelve a agregar el mismo nombre, se duplica (responsabilidad del llamador evitar duplicados). |
pub fn get_idx(&self, nombre: SymId) -> Option<usize> | Busca el índice de un campo por su nombre (SymId). Retorna None si el campo no existe en esta clase. |
pub fn len(&self) -> usize | Retorna la cantidad total de campos registrados en este shape. |
ClassDescriptor — Descriptor Completo de Clase
Estructura ClassDescriptor
pub struct ClassDescriptor {
pub nombre: SymId,
pub shape: Shape,
pub mro: Vec<SymId>,
pub metodos: HashMap<SymId, SymId>,
pub rasgos: Vec<SymId>,
} Campos
| Campo | Tipo | Descripción |
|---|---|---|
nombre | SymId | Identificador de símbolo del nombre de la clase. |
shape | Shape | La estructura de campos compartida (field layout). |
mro | Vec<SymId> | Method Resolution Order: lista ordenada de clases ancestrales. El primer elemento es la clase misma, seguida de su padre directo, abuelo, etc. Se usa para resolver métodos por herencia. |
metodos | HashMap<SymId, SymId> | Mapa de nombre de método (SymId) a nombre de función (SymId con formato "Clase.metodo"). Permite resolución O(1) de métodos en la VM. |
rasgos | Vec<SymId> | Lista de nombres de rasgos (traits) que esta clase implementa. Se poblada durante el análisis semántico. |
Ciclo de vida del ClassDescriptor
- Parsing: El Parser detecta la declaración
clase Nombre { ... }y construye unClassDescriptorcon su shape (campos) y métodos. - Semántica: El TypeChecker valida tipos de campos y firmas de métodos. El BorrowChecker verifica accesos a
este. Se resuelve el MRO. - Bytecode:
BytecodeGeneratorusa el descriptor para emitir opcodes de instanciación, acceso a campos y llamadas a métodos. - VM:
ForjaFastalmacena los descriptores enclass_descriptorsy los usa en ejecución paraGetField,SetField,CallMethody las inline caches.
Integración con otras partes del sistema
- SymbolTable: Todos los nombres (clases, campos, métodos) se almacenan como
SymIdpara comparación O(1). - VM Fast (vm_fast.rs): Contiene el vector
class_descriptors: Vec<ClassDescriptor>y el mapaclass_map: HashMap<SymId, u32>. Las inline caches (IC) enForjaFast.ic_getfieldyic_setfieldaceleran el acceso a campos cacheando el class ID. - Serializer:
ClassDescriptorno se serializa directamente; la serialización de bytecode incluye los nombres de clase que la VM luego resuelve contra su tabla de descriptores.