cgen 0.16.4 → 0.16.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/History.txt +15 -0
- data/lib/cgen/cgen.rb +14 -1
- data/lib/cgen/cshadow.rb +75 -20
- data/rakefile +2 -0
- metadata +4 -4
data/History.txt
CHANGED
@@ -1,3 +1,18 @@
|
|
1
|
+
cgen 0.16.5
|
2
|
+
|
3
|
+
- api addition: define_inheritable_c_function
|
4
|
+
|
5
|
+
- optimization: if mark and free same as parent class
|
6
|
+
implementation, reference the latter directly
|
7
|
+
|
8
|
+
- optimization: preserve Makefile mtime when nothing changes
|
9
|
+
|
10
|
+
- optimization: do not generate load and dump methods when
|
11
|
+
super implementation is equivalent
|
12
|
+
|
13
|
+
- optimization: if mark or free do nothing, don't generate a function,
|
14
|
+
just use 0 or -1 (resp.) in Data_Make_Struct
|
15
|
+
|
1
16
|
cgen 0.16.4
|
2
17
|
|
3
18
|
- api addition: module and symbol declarations can optionally be sent
|
data/lib/cgen/cgen.rb
CHANGED
@@ -418,7 +418,7 @@ require 'cgen/inherit'
|
|
418
418
|
# way that makes clear that the problem is really with commit.
|
419
419
|
module CGenerator
|
420
420
|
|
421
|
-
VERSION = '0.16.
|
421
|
+
VERSION = '0.16.5'
|
422
422
|
|
423
423
|
class Accumulator ## should be a mixin? "Cumulative"?
|
424
424
|
|
@@ -949,9 +949,22 @@ class Library < Template
|
|
949
949
|
need_to_make_clean = true
|
950
950
|
end
|
951
951
|
|
952
|
+
## it would be better to capture the output of extconf.rb before
|
953
|
+
## it writes it to Makefile, but mkmf.rb is not written that way :(
|
954
|
+
if File.exist?("Makefile")
|
955
|
+
old_makefile = File.read("Makefile")
|
956
|
+
require 'fileutils'
|
957
|
+
FileUtils.mv("Makefile", "Makefile.old")
|
958
|
+
end
|
959
|
+
|
952
960
|
system %{
|
953
961
|
#{ruby} extconf.rb > #{@logname}
|
954
962
|
}
|
963
|
+
|
964
|
+
if old_makefile and old_makefile == File.read("Makefile")
|
965
|
+
FileUtils.rm("Makefile")
|
966
|
+
FileUtils.mv("Makefile.old", "Makefile")
|
967
|
+
end
|
955
968
|
end
|
956
969
|
|
957
970
|
make "clean" if need_to_make_clean
|
data/lib/cgen/cshadow.rb
CHANGED
@@ -123,7 +123,8 @@ require "cgen/attribute"
|
|
123
123
|
# simplicity, CShadow defines three methods in the client class for defining
|
124
124
|
# methods and class methods:
|
125
125
|
#
|
126
|
-
# CShadow.define_c_method
|
126
|
+
# CShadow.define_c_method
|
127
|
+
# CShadow.define_c_class_method
|
127
128
|
# CShadow.define_c_function
|
128
129
|
#
|
129
130
|
# ===Memory management
|
@@ -269,8 +270,11 @@ module CShadow
|
|
269
270
|
classes.each do |cl|
|
270
271
|
# make sure the following have been defined by now
|
271
272
|
cl.shadow_struct
|
272
|
-
cl.new_method; cl.
|
273
|
-
cl.
|
273
|
+
cl.new_method; cl._alloc_method
|
274
|
+
cl.check_inherited_functions
|
275
|
+
if cl == cl.base_class
|
276
|
+
cl._dump_data_method; cl._load_data_method
|
277
|
+
end
|
274
278
|
end
|
275
279
|
end
|
276
280
|
|
@@ -535,7 +539,9 @@ module CShadow
|
|
535
539
|
m
|
536
540
|
end
|
537
541
|
|
538
|
-
# Define a
|
542
|
+
# Define a function in the library of this class. By
|
543
|
+
# default, the function has extern scope.
|
544
|
+
# The +name+ is just the function name (as a C function).
|
539
545
|
def define_c_function name, subclass = CGenerator::Function, &block
|
540
546
|
sf = shadow_library_source_file
|
541
547
|
m = sf.define_c_function name, subclass
|
@@ -543,9 +549,38 @@ module CShadow
|
|
543
549
|
m.instance_eval(&block) if block
|
544
550
|
m
|
545
551
|
end
|
546
|
-
|
552
|
+
|
553
|
+
# Define a function in the library of this class. By
|
554
|
+
# default, the function has extern scope.
|
555
|
+
# The +name+ is typically a symbol (like :mark) which is used to
|
556
|
+
# generate a function name in combination with the shadow struct name.
|
557
|
+
#
|
558
|
+
# If a class defines a function with +name+, and the child class does
|
559
|
+
# not do so (i.e. doesn't instantiate the function template to add
|
560
|
+
# code), then the child can call the parent's implementation using
|
561
|
+
# #refer_to_function (see #new_method for an example).
|
562
|
+
def define_inheritable_c_function name,
|
563
|
+
subclass = CGenerator::Function, &block
|
564
|
+
sf = shadow_library_source_file
|
565
|
+
m = sf.define_c_function "#{name}_#{shadow_struct.name}", subclass
|
566
|
+
c_function_templates[name] = m
|
567
|
+
m.scope :extern
|
568
|
+
m.instance_eval(&block) if block
|
569
|
+
m
|
570
|
+
end
|
571
|
+
|
547
572
|
#== Internal methods ==#
|
548
573
|
|
574
|
+
def c_function_templates; @c_function_templates ||= {}; end
|
575
|
+
# Note that {} nondeterministic, so these should only be used to
|
576
|
+
# check existence or get value, not to iterate.
|
577
|
+
|
578
|
+
def find_super_function sym
|
579
|
+
c_function_templates[sym] || (
|
580
|
+
defined?(superclass.find_super_function) &&
|
581
|
+
superclass.find_super_function(sym))
|
582
|
+
end
|
583
|
+
|
549
584
|
# Construct the name used for the shadow struct.
|
550
585
|
def shadow_struct_name
|
551
586
|
name.gsub(/_/, '__').gsub(/::/, '_o_') + CShadow::SHADOW_SUFFIX
|
@@ -582,6 +617,8 @@ module CShadow
|
|
582
617
|
unless defined?(@new_method) and @new_method
|
583
618
|
sf = shadow_library_source_file
|
584
619
|
ssn = shadow_struct.name
|
620
|
+
mark_name = refer_to_function :mark
|
621
|
+
free_name = refer_to_function :free
|
585
622
|
@new_method = sf.define_c_singleton_method self,
|
586
623
|
:new, AttrClassMethod
|
587
624
|
@new_method.instance_eval {
|
@@ -592,11 +629,11 @@ module CShadow
|
|
592
629
|
setup :shadow_struct => %{
|
593
630
|
object = Data_Make_Struct(self,
|
594
631
|
#{ssn},
|
595
|
-
|
596
|
-
|
632
|
+
#{mark_name},
|
633
|
+
#{free_name},
|
597
634
|
shadow);
|
598
635
|
shadow->self = object;
|
599
|
-
}
|
636
|
+
}
|
600
637
|
body attr_code!
|
601
638
|
body %{
|
602
639
|
rb_obj_call_init(object, argc, argv);
|
@@ -609,18 +646,37 @@ module CShadow
|
|
609
646
|
end
|
610
647
|
@new_method
|
611
648
|
end
|
612
|
-
|
649
|
+
|
650
|
+
def referenced_functions
|
651
|
+
@referenced_functions ||= {}
|
652
|
+
end
|
653
|
+
|
654
|
+
def refer_to_function sym
|
655
|
+
referenced_functions[sym] = true
|
656
|
+
"#{sym}_#{shadow_struct.name}"
|
657
|
+
end
|
658
|
+
|
659
|
+
def check_inherited_functions
|
660
|
+
syms = referenced_functions.keys.sort_by{|k|k.to_s}
|
661
|
+
syms.reject {|sym| c_function_templates[sym]}.each do |sym|
|
662
|
+
fname = "#{sym}_#{shadow_struct.name}"
|
663
|
+
pf = find_super_function(sym)
|
664
|
+
pf_str = pf ? pf.name : (sym == :free ? -1 : 0)
|
665
|
+
# -1 means free the struct; See README.EXT
|
666
|
+
shadow_library_source_file.declare fname.intern =>
|
667
|
+
"#define #{fname} #{pf_str}"
|
668
|
+
end
|
669
|
+
end
|
670
|
+
|
613
671
|
# Return the object for managing the mark function of the class.
|
614
672
|
def mark_function
|
615
673
|
unless defined?(@mark_function) and @mark_function
|
616
674
|
sf = shadow_library_source_file
|
617
675
|
ssn = shadow_struct.name
|
618
|
-
@mark_function =
|
619
|
-
@mark_function.instance_eval {
|
620
|
-
scope :static
|
676
|
+
@mark_function = define_inheritable_c_function(:mark, MarkFunction) do
|
621
677
|
arguments "#{ssn} *shadow"
|
622
678
|
return_type "void"
|
623
|
-
|
679
|
+
end
|
624
680
|
if superclass.respond_to? :shadow_struct
|
625
681
|
@mark_function.mark superclass.mark_function.mark!
|
626
682
|
end
|
@@ -633,12 +689,10 @@ module CShadow
|
|
633
689
|
unless defined?(@free_function) and @free_function
|
634
690
|
sf = shadow_library_source_file
|
635
691
|
ssn = shadow_struct.name
|
636
|
-
@free_function =
|
637
|
-
@free_function.instance_eval {
|
638
|
-
scope :static
|
692
|
+
@free_function = define_inheritable_c_function(:free, FreeFunction) do
|
639
693
|
arguments "#{ssn} *shadow"
|
640
694
|
return_type "void"
|
641
|
-
|
695
|
+
end
|
642
696
|
if superclass.respond_to? :shadow_struct
|
643
697
|
@free_function.free superclass.free_function.free!
|
644
698
|
end
|
@@ -690,6 +744,8 @@ module CShadow
|
|
690
744
|
unless defined?(@_alloc_method) and @_alloc_method
|
691
745
|
sf = shadow_library_source_file
|
692
746
|
ssn = shadow_struct.name
|
747
|
+
mark_name = refer_to_function :mark
|
748
|
+
free_name = refer_to_function :free
|
693
749
|
@_alloc_method = sf.define_alloc_func(self)
|
694
750
|
@_alloc_method.instance_eval {
|
695
751
|
scope :extern
|
@@ -701,8 +757,8 @@ module CShadow
|
|
701
757
|
body %{
|
702
758
|
object = Data_Make_Struct(#{klass_c_name},
|
703
759
|
#{ssn},
|
704
|
-
|
705
|
-
|
760
|
+
#{mark_name},
|
761
|
+
#{free_name},
|
706
762
|
shadow);
|
707
763
|
shadow->self = object;
|
708
764
|
}
|
@@ -899,7 +955,6 @@ module CShadow
|
|
899
955
|
end
|
900
956
|
|
901
957
|
unless base_class.ancestors.include? self
|
902
|
-
|
903
958
|
base_class.class_eval {@base_class = self; @persistent = true}
|
904
959
|
base_class.extend CShadowClassMethods
|
905
960
|
|
data/rakefile
CHANGED
@@ -30,6 +30,8 @@ END
|
|
30
30
|
test.files = Dir["test/test-*.rb"]
|
31
31
|
}
|
32
32
|
|
33
|
+
ENV["VERSION"] = CGenerator::VERSION ## why isn't this automatic?
|
34
|
+
|
33
35
|
task 'gem:release' => 'rubyforge:release' # to release to rubyforge as well
|
34
36
|
|
35
37
|
task :release => ["rubyforge:release", "rubyforge:doc_release"]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cgen
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 85
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 16
|
9
|
-
-
|
10
|
-
version: 0.16.
|
9
|
+
- 5
|
10
|
+
version: 0.16.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joel VanderWerf
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-07-08 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|