Class: Furnace::AVM2::ABC::Record
- Inherits:
-
Binary::Record
- Object
- Binary::Record
- Furnace::AVM2::ABC::Record
- Defined in:
- lib/furnace-avm2/abc/primitives/record.rb
Direct Known Subclasses
ConstPoolInfo, DefaultValue, ExceptionInfo, File, InstanceInfo, KlassInfo, MetadataInfo, MethodBodyInfo, MethodInfo, MultinameInfo, MultinameKindGenericName, MultinameKindMultiname, MultinameKindMultinameL, MultinameKindQName, MultinameKindRTQName, MultinameKindRTQNameL, NamespaceInfo, NsSetInfo, ScriptInfo, TraitClass, TraitFunction, TraitInfo, TraitMethod, TraitSlot
Instance Attribute Summary
Attributes inherited from Binary::Record
Class Method Summary collapse
- .abc_array_of(name, type, options = {}) ⇒ Object
-
.flag(name, field, constant) ⇒ Object
Flags.
- .pool_array(pool, name, type, options = {}) ⇒ Object
- .pool_array_of(pool, name, type, options = {}) ⇒ Object
-
.pool_ref(pool, name, type = name, options = {}) ⇒ Object
Pools.
-
.subset(name, array, selector) ⇒ Object
Subsetting.
-
.xlat_direct ⇒ Object
Xlat.
- .xlat_field(name) ⇒ Object
- .xlat_inverse ⇒ Object
Methods inherited from Binary::Record
#byte_length, codegen, codegen_each, inherited, #inspect, method_missing, register, #to_hash, trace, trace_scope, trace_value
Class Method Details
.abc_array_of(name, type, options = {}) ⇒ Object
3 4 5 6 7 8 9 10 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 3 def self.abc_array_of(name, type, ={}) field_size, field_array = :"#{name}_count", .delete(:plural) || :"#{name}s" klass = .delete(:class) vuint30 field_size, { :value => lambda { send(field_array).count } }.merge() array field_array, { :type => type, :initial_length => field_size, :options => { :class => klass } }.merge() end |
.flag(name, field, constant) ⇒ Object
Flags
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 139 def self.flag(name, field, constant) define_method(:"#{name}?") do instance_variable_get(:"@#{field}") & constant != 0 end define_method(:"#{name}=") do |is_set| flags = instance_variable_get(:"@#{field}") if is_set instance_variable_set(:"@#{field}", flags | constant) else instance_variable_set(:"@#{field}", flags & ~constant) end end end |
.pool_array(pool, name, type, options = {}) ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 66 def self.pool_array(pool, name, type, ={}) field, type_plural = :"#{name}_raw", .delete(:plural) || :"#{type}s" array field, { :type => :vuint30 }.merge() if pool == :root define_method(name) do send(field).map do |element| root.send(type_plural)[element] end end elsif pool == :const define_method(name) do send(field).map do |element| if element == 0 nil else root.constant_pool.send(type_plural)[element - 1] end end end end end |
.pool_array_of(pool, name, type, options = {}) ⇒ Object
90 91 92 93 94 95 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 90 def self.pool_array_of(pool, name, type, ={}) field_size, field_array = :"#{name}_count", .delete(:plural) || :"#{name}s" vuint30 field_size, { :value => lambda { send(field_array).count } }.merge() pool_array pool, field_array, type, { :initial_length => field_size }.merge() end |
.pool_ref(pool, name, type = name, options = {}) ⇒ Object
Pools
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 14 def self.pool_ref(pool, name, type=name, ={}) field, array = :"#{name}_idx", .delete(:plural) || :"#{type}s" vuint30 field, if pool == :root define_method(name) do root.send(array)[send(field)] end elsif pool == :const define_method(name) do index = send(field) if index == 0 nil else root.constant_pool.send(array)[index - 1] end end define_method(:"#{name}=") do |value| pool = root.constant_pool.send(array) if value.nil? send(:"#{field}=", 0) elsif index = pool.index(value) send(:"#{field}=", index + 1) else format_entry = ConstPoolInfo.format.find { |f| f[1] == array } if format_entry.nil? raise "cpool setter: [BUG] no such cpool field" end klass = nil case format_entry[2][:type] when :vstring; klass = String when :nested; klass = format_entry[2][:class] end if klass.nil? raise "cpool setter: [BUG] no checker for type #{format_entry[2][:type]}" end if value.class != klass raise "cpool setter: trying to set wrong kind of value (#{value.class} instead of #{klass})" end pool.push value send(:"#{field}=", pool.index(value) + 1) end end end end |
.subset(name, array, selector) ⇒ Object
Subsetting
157 158 159 160 161 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 157 def self.subset(name, array, selector) define_method(:"#{name}") do send(array).select &selector end end |
.xlat_direct ⇒ Object
Xlat
109 110 111 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 109 def self.xlat_direct @xlat_direct ||= const_get(:XlatTable).invert end |
.xlat_field(name) ⇒ Object
117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 117 def self.xlat_field(name) define_method(:"#{name}") do value = instance_variable_get :"@#{name}_raw" unless self.class.xlat_direct.has_key? value raise ArgumentError, "Unknown xlat value #{value} for #{self.class}" end self.class.xlat_direct[value] end define_method(:"#{name}=") do |new_value| unless self.class.xlat_inverse.has_key? new_value raise ArgumentError, "Unknown xlat identifier #{new_value} for #{self.class}" end instance_variable_set :"@#{name}_raw", self.class.xlat_inverse[new_value] end end |
.xlat_inverse ⇒ Object
113 114 115 |
# File 'lib/furnace-avm2/abc/primitives/record.rb', line 113 def self.xlat_inverse @xlat_inverse ||= const_get(:XlatTable) end |