| 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…
| MAGIC | = | 3405691582 |
| access | [RW] | |
| attrs | [RW] | |
| fields | [RW] | |
| interfaces | [RW] | |
| magic | [RW] | |
| major | [RW] | |
| methods | [RW] | |
| minor | [RW] | |
| pool | [RW] | |
| super_class | [RW] | |
| this_class | [RW] |
# 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
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)
# 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
# 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
# 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
# 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
# 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