Class Ruva::VM::Class::Reader::UnresolvedClass
In: lib/ruva/class_loader.rb
Parent: UnresolvedMember

An unresolved class is just an interim holder used during reading. It can be used informationally as-is, or can be visited by a Ruva::VM::Class to create a resolved class.

This is all a bit internal…

Methods

Classes and Modules

Class Ruva::VM::Class::Reader::UnresolvedClass::AttributeEntry
Class Ruva::VM::Class::Reader::UnresolvedClass::CPoolEntry
Class Ruva::VM::Class::Reader::UnresolvedClass::FieldEntry
Class Ruva::VM::Class::Reader::UnresolvedClass::MemberEntry
Class Ruva::VM::Class::Reader::UnresolvedClass::MethodEntry

Constants

MAGIC = 3405691582

Attributes

access  [RW] 
attrs  [RW] 
fields  [RW] 
interfaces  [RW] 
magic  [RW] 
major  [RW] 
methods  [RW] 
minor  [RW] 
pool  [RW] 
super_class  [RW] 
this_class  [RW] 

Public Class methods

[Source]

     # File lib/ruva/class_loader.rb, line 406
406:           def initialize(magic, major, minor)
407:             super(self)            
408:             
409:             raise VMError, "Invalid class format signature" unless magic == MAGIC 
410:             raise VMError, "Unsupported class format version #{major}.#{minor}" if Float("#{major}.#{minor}") > 49.0
411:             self.magic = magic
412:             self.major, self.minor = major, minor
413:             
414:             self.access = 0
415:             self.this_class, self.super_class = nil, nil
416:             self.pool, self.interfaces, self.fields, self.methods, self.attrs = [], [], [], [], []
417:           end

Public Instance methods

Cause the supplied visitor to traverse this class, during which constant-pool resolution can be performed. The visitor is usually a Ruva::VM::Class instance. This method returns the visitor for easier usage, e.g.

  clz = uclz.accept(Class.new)

[Source]

     # File lib/ruva/class_loader.rb, line 425
425:           def accept(cv)
426:             # non-standard attributes            
427:             cv.visit(major, minor, access, name, signature, super_name, interface_names)
428:                         
429:             do_visit_const_pool(cv)     
430:             do_visit_annotations(cv)      # TODO annotations don't work
431:             do_visit_std_attrs(cv)  
432:             other_attrs.each { |a| cv.visit_attribute(a) }
433:             
434:             fields.each do |f|
435:               fv = cv.visit_field(f.access, pool[f.name_index - 1].data, pool[f.descriptor_index - 1].data, f.signature, f.const_value)
436: 
437:               f.do_visit_std_attrs(fv)  
438:               f.other_attrs.each { |a| fv.visit_attribute(a) }
439:               f.do_visit_annotations(fv)
440:               fv.visit_end
441:             end
442:             
443:             methods.each do |m|
444:               throws = m.throws.map { |i| pool[pool[i - 1].data[:name_index] - 1].data }
445:               mv = cv.visit_method(m.access, pool[m.name_index - 1].data, pool[m.descriptor_index - 1].data, m.signature, throws)
446:               m.do_visit_std_attrs(mv)  
447:               m.other_attrs.each { |a| mv.visit_attribute(a) }
448:               m.do_visit_annotations(mv)
449:               
450:               if code = m.code_attr               
451:                 mv.visit_maxs(code.data[:max_stack], code.data[:max_locals])
452:                 mv.visit_code(code.data[:code])
453:                 
454:                 code.data[:exceptions].each do |ex|   
455:                   # TODO where are these catches with type 0 coming from?
456:                   unless ex[:catch_type] == 0
457:                     mv.visit_exception_handler(ex[:start_pc], ex[:end_pc], ex[:handler_pc], pool[pool[ex[:catch_type] - 1].data[:name_index] - 1].data)
458:                   end
459:                 end
460:                                   
461:                 code.do_visit_std_attrs(mv)
462:               else
463:                 raise VMError, "No Code attribute found on non-abstract method #{m.name}" unless m.access || 0x0400 == 0 # abstract
464:               end
465:               
466:               mv.visit_end
467:             end
468:             
469:             cv.visit_end
470:             cv
471:           end

[Source]

     # File lib/ruva/class_loader.rb, line 491
491:           def interface_names
492:             self.interfaces.map { |idx| pool[pool[idx - 1].data[:name_index] - 1].data }
493:           end

[Source]

     # File lib/ruva/class_loader.rb, line 473
473:           def name
474:             if this_class
475:               pool[pool[this_class - 1].data[:name_index] - 1].data
476:             end
477:           end

[Source]

     # File lib/ruva/class_loader.rb, line 479
479:           def signature
480:             if sig = attrs.find { |e| e.name == "Signature" }
481:               pool[sig.data - 1].data
482:             end              
483:           end

[Source]

     # File lib/ruva/class_loader.rb, line 485
485:           def super_name
486:             if super_class > 0
487:               pool[pool[super_class - 1].data[:name_index] - 1].data
488:             end
489:           end

Protected Instance methods

[Source]

     # File lib/ruva/class_loader.rb, line 497
497:           def do_visit_const_pool(cv)
498:             pool.each { |e| cv.visit_cpool_entry(pool, e.data, e.type) }
499:           end

[Validate]