cgen 0.16.4 → 0.16.5
Sign up to get free protection for your applications and to get access to all the features.
- 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
|