Class: CShadow::ShadowObjectAttribute

Inherits:
Attribute
  • Object
show all
Defined in:
lib/cgen/attribute.rb

Overview

There are two kinds of object attributes. Both refer to Ruby objects and can be typed or untyped. This one is a slightly optimized variation that is restricted to references to other shadow objects.

ShadowObjectAttribute is a restricted variant of ObjectAttribute in which the object referred to must belong to a class that includes CShadow. The actual pointer is to the shadow struct itself, rather than a VALUE. This difference is transparent to Ruby code. The syntax for this variant differs only in the use of brackets around the type. For example, using the class A defined above:

class B
  include CShadow
  shadow_attr_accessor :a => [A]

  def initialize
    self.a = A.new
    a.sym = :something
  end
end

Note that a shadow struct always has a self pointer, so a ShadowObjectAttribute contains essentially the same information as an ObjectAttribute. It is included for situation in which the efficiency of a direct reference to the shadow struct is desirable. Note that only ObjectAttributes can refer to general Ruby objects which may or may not include the CShadow module.

The accessors work just as with ObjectAttribute, with type checking performed by the writer. From Ruby, these two kinds of attributes are indistinguishable in all respects except their declaration syntax.

The referenced Ruby object is marked to protect it from the garbage collector.

Instance Attribute Summary

Attributes inherited from Attribute

#cdecl, #check, #cvar, #dump, #free, #init, #load, #mark, #owner_class, #persists, #reader, #var, #writer

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from Attribute

inherited

Constructor Details

#initialize(*args) ⇒ ShadowObjectAttribute

Returns a new instance of ShadowObjectAttribute.



198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/cgen/attribute.rb', line 198

def initialize(*args)
  super
  @class = @match
  
  ssn = @class.shadow_struct_name
  
  @cvar = @var
  if @class < CShadow
    @cdecl = "struct #{ssn} *#{@cvar}"
  else
    raise ScriptError, "Class #{@class} doesn't include CShadow."
  end
  
  @reader = "result = shadow->#{@cvar} ? shadow->#{@cvar}->self : Qnil"
  @writer = %{
    if (arg != Qnil) {
      Data_Get_Struct(arg, #{ssn}, shadow->#{@cvar});
    } else
      shadow->#{@cvar} = 0;
  }
  @check = @class unless @class == Object
  @mark = %{\
    if (shadow->#{@cvar})
      rb_gc_mark(shadow->#{@cvar}->self);\
  }
  
  @dump =
    "rb_ary_push(result, shadow->#{@cvar} ? shadow->#{@cvar}->self : 0)"
  @load = %{
      tmp = rb_ary_shift(from_array);
      if (tmp) {
        Data_Get_Struct(tmp, #{ssn}, shadow->#{@cvar});
      } else
        shadow->#{@cvar} = 0;
  }
end

Class Method Details

.match(decl) ⇒ Object



192
193
194
# File 'lib/cgen/attribute.rb', line 192

def ShadowObjectAttribute.match decl
  decl[0] if decl.is_a? Array and decl.size == 1 and decl[0].is_a? Class
end

Instance Method Details

#inspectObject



235
236
237
# File 'lib/cgen/attribute.rb', line 235

def inspect
  %{<#{self.class} #{@cvar} => [#{@class.inspect}]>}
end

#target_classObject



196
# File 'lib/cgen/attribute.rb', line 196

def target_class; @class; end