redshift 1.3.21 → 1.3.22
Sign up to get free protection for your applications and to get access to all the features.
- data/RELEASE-NOTES +14 -0
- data/bench/algebraic.rb +61 -0
- data/bench/bench +3 -0
- data/bench/connect.rb +75 -0
- data/bench/linked-flows.rb +71 -0
- data/examples/step-discrete-hook.rb +201 -0
- data/lib/redshift/component.rb +4 -1
- data/lib/redshift/meta.rb +2 -0
- data/lib/redshift/mixins/zeno-debugger.rb +1 -1
- data/lib/redshift/redshift.rb +48 -11
- data/lib/redshift/syntax.rb +9 -1
- data/lib/redshift/target/c/component-gen.rb +185 -91
- data/lib/redshift/target/c/flow-gen.rb +11 -9
- data/lib/redshift/target/c/flow/algebraic.rb +32 -37
- data/lib/redshift/target/c/flow/delay.rb +34 -32
- data/lib/redshift/target/c/flow/derivative.rb +30 -33
- data/lib/redshift/target/c/flow/euler.rb +24 -22
- data/lib/redshift/target/c/flow/expr.rb +40 -43
- data/lib/redshift/target/c/flow/rk4.rb +28 -32
- data/lib/redshift/target/c/library.rb +2 -8
- data/lib/redshift/target/c/world-gen.rb +31 -35
- data/lib/redshift/world.rb +6 -0
- metadata +12 -14
- data/.bnsignore +0 -27
- data/bench/after-flow-cache +0 -66
- data/bench/before-flow-cache +0 -66
data/lib/redshift/component.rb
CHANGED
@@ -88,8 +88,11 @@ class Flow ## rename to equation? formula? put in meta?
|
|
88
88
|
# steps of the discrete update. This can be false only for an AlgebraicFlow
|
89
89
|
# which depends on non-strict variables. In the algebraic case, a flow is
|
90
90
|
# strict iff the RHS of the eqn. has only strictly continuous variables.
|
91
|
+
# Guards are not flows (except by inheritance); CexprGuard instances may be
|
92
|
+
# non-strict. Reset expressions (Exprs) always evaluate, so strictness does
|
93
|
+
# not apply.
|
91
94
|
attr_reader :strict
|
92
|
-
|
95
|
+
|
93
96
|
def initialize v, f
|
94
97
|
@var, @formula = v, f
|
95
98
|
@strict = true
|
data/lib/redshift/meta.rb
CHANGED
data/lib/redshift/redshift.rb
CHANGED
@@ -1,22 +1,59 @@
|
|
1
1
|
# Copyright (C) 2001-2010, Joel VanderWerf
|
2
2
|
# Distributed under the Ruby license. See www.ruby-lang.org.
|
3
3
|
|
4
|
-
#
|
5
|
-
|
4
|
+
# RedShift has no command line interface, since it is a library. But it does
|
5
|
+
# let you pass in options with any env var named REDSHIFT_*. The variable
|
6
|
+
# is accessible as a global $REDSHIFT_*.
|
7
|
+
#
|
8
|
+
# Some standard env vars recognized by redshift itself:
|
9
|
+
#
|
10
|
+
# REDSHIFT_BUILD_TIMES : boolean - show times of each build step
|
11
|
+
# REDSHIFT_CGEN_VERBOSE : boolean - passed on to cgen via $CGEN_VERBOSE
|
12
|
+
# REDSHIFT_CLIB_NAME : string - used as based for dir and .so names
|
13
|
+
# REDSHIFT_DEBUG : int - debug level (false, 0, or empty to disable)
|
14
|
+
# REDSHIFT_DEBUG_ZENO : boolean - turn on Zeno debugging in zeno-debugger.rb
|
15
|
+
# REDSHIFT_MAKE_ARGS : string - arguments passed on to make (-j is nice)
|
16
|
+
# REDSHIFT_SKIP_BUILD : boolean - just load .so and run program
|
17
|
+
# REDSHIFT_TARGET : string - (future) which kind of build
|
18
|
+
# REDSHIFT_WORK_DIR : string - where to build C lib (default is ./tmp/)
|
19
|
+
|
20
|
+
convert_val = proc do |var, val|
|
21
|
+
case var
|
22
|
+
when /\AREDSHIFT_(?:BUILD_TIMES|CGEN_VERBOSE|DEBUG_ZENO|SKIP_BUILD)\z/
|
23
|
+
case val
|
24
|
+
when /\A\s*(false|off|nil|0*)\s*\z/i
|
25
|
+
false
|
26
|
+
else
|
27
|
+
true
|
28
|
+
end
|
29
|
+
when /\AREDSHIFT_DEBUG\z/
|
30
|
+
case val
|
31
|
+
when /\A\s*(false|off|nil|0*)\s*\z/i
|
32
|
+
false
|
33
|
+
when /\A\s*(true|on)\s*\z/i
|
34
|
+
1
|
35
|
+
else
|
36
|
+
val.to_i rescue 1
|
37
|
+
end
|
38
|
+
else
|
39
|
+
val
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
6
43
|
ENV.keys.grep(/RedShift/i) do |key|
|
44
|
+
next unless /\A[\w]+\z/ =~ key
|
7
45
|
val = ENV[key] # make eval safe
|
46
|
+
val = convert_val[key, val]
|
8
47
|
eval "$#{key} = val unless defined? $#{key}"
|
9
48
|
end
|
10
49
|
|
11
50
|
if $REDSHIFT_DEBUG
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
$REDSHIFT_DEBUG = ($REDSHIFT_DEBUG.to_i rescue 1)
|
51
|
+
$stderr.puts <<-EOS
|
52
|
+
-----------------------------------------------------------------
|
53
|
+
|RedShift debugging information enabled by env var REDSHIFT_DEBUG.|
|
54
|
+
-----------------------------------------------------------------
|
55
|
+
REDSHIFT_DEBUG = #{$REDSHIFT_DEBUG}
|
56
|
+
EOS
|
20
57
|
end
|
21
58
|
|
22
59
|
class AssertionFailure < StandardError; end
|
@@ -33,7 +70,7 @@ end
|
|
33
70
|
module RedShift
|
34
71
|
include Math
|
35
72
|
|
36
|
-
VERSION = '1.3.
|
73
|
+
VERSION = '1.3.22'
|
37
74
|
|
38
75
|
Infinity = Math::Infinity
|
39
76
|
|
data/lib/redshift/syntax.rb
CHANGED
@@ -402,13 +402,21 @@ module TransitionSyntax
|
|
402
402
|
end
|
403
403
|
alias after post
|
404
404
|
|
405
|
-
# +h+ is a hash of :var => proc {value_expr_ruby} or "value_expr_c".
|
405
|
+
# +h+ is a hash of :var => proc {value_expr_ruby} or "value_expr_c" or a literal.
|
406
406
|
def reset(h)
|
407
407
|
badkeys = h.keys.reject {|k| k.is_a?(Symbol)}
|
408
408
|
unless badkeys.empty?
|
409
409
|
raise SyntaxError, "Keys #{badkeys.inspect} in reset must be symbols"
|
410
410
|
end
|
411
411
|
|
412
|
+
h.keys.each do |k|
|
413
|
+
v = h[k]
|
414
|
+
case v
|
415
|
+
when String
|
416
|
+
h[k] = v.strip
|
417
|
+
end
|
418
|
+
end
|
419
|
+
|
412
420
|
@resets ||= Component::ResetPhase.new
|
413
421
|
@resets.value_map ||= {}
|
414
422
|
@resets.concat [nil, nil, nil] # continuous, constant, link
|
@@ -57,10 +57,8 @@ module RedShift
|
|
57
57
|
unsigned ck_strict : 1; // should check strict at end of phase
|
58
58
|
unsigned reset : 1; // var is being reset
|
59
59
|
Flow flow; // cached flow function of current state
|
60
|
-
double
|
61
|
-
|
62
|
-
double value_2;
|
63
|
-
double value_3;
|
60
|
+
double value[4]; // [0] = value during discrete step
|
61
|
+
// [1..3] = value at steps of Runge-Kutta
|
64
62
|
} ContVar;
|
65
63
|
#ifdef WIN32
|
66
64
|
#pragma pack(pop)
|
@@ -96,52 +94,65 @@ module RedShift
|
|
96
94
|
|
97
95
|
def initialize(*args)
|
98
96
|
super
|
99
|
-
#
|
100
|
-
@dump = "rb_ary_push(result, rb_float_new(shadow->#{@cvar}.
|
101
|
-
@load = "shadow->#{@cvar}.
|
97
|
+
# value[0] is the relevant state outside of continuous update
|
98
|
+
@dump = "rb_ary_push(result, rb_float_new(shadow->#{@cvar}.value[0]))"
|
99
|
+
@load = "shadow->#{@cvar}.value[0] = NUM2DBL(rb_ary_shift(from_array))"
|
102
100
|
end
|
103
101
|
end
|
102
|
+
|
103
|
+
def Component.store_wrapper name, wrapper
|
104
|
+
raise unless self == Component
|
105
|
+
@fn_wrapper_by_name ||= {}
|
106
|
+
@fn_wrapper_by_name[name] = wrapper
|
107
|
+
end
|
104
108
|
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
class SingletonShadowClass
|
109
|
-
include Singleton
|
110
|
-
include CShadow; shadow_library Component
|
111
|
-
persistent false
|
112
|
-
def inspect; self.class.inspect_str; end
|
113
|
-
class << self; attr_reader :inspect_str; end
|
109
|
+
def Component.fetch_wrapper name
|
110
|
+
raise unless self == Component
|
111
|
+
@fn_wrapper_by_name && @fn_wrapper_by_name[name]
|
114
112
|
end
|
115
113
|
|
116
114
|
# FunctionWrappers wrap function pointers for access from ruby.
|
117
|
-
class FunctionWrapper
|
118
|
-
|
119
|
-
|
120
|
-
end
|
115
|
+
class FunctionWrapper
|
116
|
+
include CShadow; shadow_library Component
|
117
|
+
persistent false
|
121
118
|
|
122
|
-
class
|
123
|
-
|
119
|
+
class RedShift::Flow ### move this
|
120
|
+
# Function name and file name
|
121
|
+
attr_reader :fname
|
124
122
|
|
125
|
-
|
126
|
-
|
123
|
+
attr_reader :inspect_str
|
124
|
+
|
125
|
+
# proc to build the function in the file
|
126
|
+
attr_reader :generator
|
127
|
+
|
128
|
+
def generate
|
129
|
+
## create the file?
|
130
|
+
generator.call unless @generated
|
131
|
+
@generated = true
|
127
132
|
rescue => ex
|
128
|
-
ex.message << " While defining #{
|
133
|
+
ex.message << " While defining #{inspect}."
|
129
134
|
raise
|
130
135
|
end
|
131
136
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
137
|
+
# Can be called only after commit.
|
138
|
+
def wrapper
|
139
|
+
raise unless Component.committed?
|
140
|
+
Component.fetch_wrapper(fname)
|
141
|
+
end
|
142
|
+
|
143
|
+
def inspect; inspect_str; end
|
144
|
+
|
145
|
+
def become_generatable(*args)
|
146
|
+
make_generator(*args) unless generator
|
147
|
+
self
|
143
148
|
end
|
144
149
|
end
|
150
|
+
|
151
|
+
def inspect; @inspect_str; end
|
152
|
+
|
153
|
+
def initialize inspect_str
|
154
|
+
@inspect_str = inspect_str
|
155
|
+
end
|
145
156
|
end
|
146
157
|
|
147
158
|
class FlowWrapper < FunctionWrapper
|
@@ -152,10 +163,8 @@ module RedShift
|
|
152
163
|
|
153
164
|
class GuardWrapper < FunctionWrapper
|
154
165
|
shadow_attr :guard => "Guard guard"
|
166
|
+
shadow_attr_reader :strict => "boolean strict"
|
155
167
|
@tag = "Guard"
|
156
|
-
|
157
|
-
def self.strict; @strict; end
|
158
|
-
def strict; @strict ||= self.class.strict; end
|
159
168
|
end
|
160
169
|
|
161
170
|
class ExprWrapper < FunctionWrapper
|
@@ -327,7 +336,7 @@ module RedShift
|
|
327
336
|
unsigned unused : 11;
|
328
337
|
union {
|
329
338
|
struct {
|
330
|
-
unsigned idx : 16; //# index of next
|
339
|
+
unsigned idx : 16; //# index of next trans after sync failure
|
331
340
|
} trans;
|
332
341
|
} tmp;
|
333
342
|
}
|
@@ -342,10 +351,6 @@ module RedShift
|
|
342
351
|
@flow_hash ||= {}
|
343
352
|
end
|
344
353
|
|
345
|
-
def add_flow h # [state, var] => flow_wrapper_subclass, ...
|
346
|
-
flow_hash.update h
|
347
|
-
end
|
348
|
-
|
349
354
|
def flow_table
|
350
355
|
unless @flow_table
|
351
356
|
assert committed?
|
@@ -355,8 +360,8 @@ module RedShift
|
|
355
360
|
ft[k] = v.dup
|
356
361
|
end
|
357
362
|
end
|
358
|
-
for (state, var),
|
359
|
-
(ft[state] ||= [])[var.index] =
|
363
|
+
for (state, var), flow in flow_hash
|
364
|
+
(ft[state] ||= [])[var.index] = flow.wrapper
|
360
365
|
end
|
361
366
|
@flow_table = ft
|
362
367
|
end
|
@@ -386,7 +391,7 @@ module RedShift
|
|
386
391
|
var_name = var_name.intern if var_name.is_a? String
|
387
392
|
|
388
393
|
cont_state_class.add_var var_name, kind do
|
389
|
-
ssn = cont_state_class.
|
394
|
+
ssn = cont_state_class.shadow_struct_name
|
390
395
|
exc = shadow_library.declare_class(AlgebraicAssignmentError)
|
391
396
|
msg = "Cannot set #{var_name}; it is defined algebraically."
|
392
397
|
|
@@ -413,7 +418,7 @@ module RedShift
|
|
413
418
|
# later, so strictness will get checked at the end of any
|
414
419
|
# transitions (but only if someone has relied on it).
|
415
420
|
|
416
|
-
returns "rb_float_new(cont_state->#{var_name}.
|
421
|
+
returns "rb_float_new(cont_state->#{var_name}.value[0])"
|
417
422
|
end
|
418
423
|
}
|
419
424
|
|
@@ -429,7 +434,7 @@ module RedShift
|
|
429
434
|
declare :cont_state => "#{ssn} *cont_state"
|
430
435
|
body %{
|
431
436
|
cont_state = (#{ssn} *)shadow->cont_state;
|
432
|
-
cont_state->#{var_name}.
|
437
|
+
cont_state->#{var_name}.value[0] = NUM2DBL(value);
|
433
438
|
if (shadow->world)
|
434
439
|
shadow->world->d_tick++;
|
435
440
|
if (cont_state->#{var_name}.algebraic)
|
@@ -448,7 +453,7 @@ module RedShift
|
|
448
453
|
declare :cont_state => "#{ssn} *cont_state"
|
449
454
|
body %{
|
450
455
|
cont_state = (#{ssn} *)shadow->cont_state;
|
451
|
-
cont_state->#{var_name}.
|
456
|
+
cont_state->#{var_name}.value[0] = NUM2DBL(value);
|
452
457
|
if (shadow->world)
|
453
458
|
shadow->world->d_tick++;
|
454
459
|
if (cont_state->#{var_name}.algebraic)
|
@@ -549,6 +554,15 @@ module RedShift
|
|
549
554
|
|
550
555
|
check_variables
|
551
556
|
end
|
557
|
+
|
558
|
+
def generate_wrappers
|
559
|
+
hs = [flow_hash, @guard_hash, @expr_hash]
|
560
|
+
hs.compact.each do |h|
|
561
|
+
h.values.sort_by{|f| f.fname}.each do |flow|
|
562
|
+
flow.generate ### should rename Flow class to Function or such
|
563
|
+
end
|
564
|
+
end
|
565
|
+
end
|
552
566
|
|
553
567
|
def define_events
|
554
568
|
exported_events.own.each do |event, index|
|
@@ -593,7 +607,7 @@ module RedShift
|
|
593
607
|
end
|
594
608
|
|
595
609
|
def add_var_to_offset_table var_name
|
596
|
-
ssn =
|
610
|
+
ssn = shadow_struct_name
|
597
611
|
lit = shadow_library.literal_symbol(var_name,
|
598
612
|
shadow_library_source_file)
|
599
613
|
offset_table_method.body %{\
|
@@ -603,7 +617,7 @@ module RedShift
|
|
603
617
|
end
|
604
618
|
|
605
619
|
def define_links
|
606
|
-
ssn =
|
620
|
+
ssn = shadow_struct_name
|
607
621
|
|
608
622
|
link_variables.own.keys.sort_by{|k|k.to_s}.each do |var_name|
|
609
623
|
var_type, strictness = link_variables[var_name]
|
@@ -673,16 +687,18 @@ module RedShift
|
|
673
687
|
def define_flows(state)
|
674
688
|
own_flows = flows(state).own
|
675
689
|
own_flows.keys.sort_by{|sym|sym.to_s}.each do |var|
|
676
|
-
|
690
|
+
define_flow own_flows[var], state, var
|
691
|
+
end
|
692
|
+
end
|
677
693
|
|
678
|
-
|
679
|
-
|
680
|
-
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
add_flow([state, cont_var] => flow_wrapper(flow, state))
|
694
|
+
def define_flow flow, state, var
|
695
|
+
cont_var = cont_state_class.vars[var]
|
696
|
+
unless cont_var
|
697
|
+
attach_continuous_variables(:permissive, [var])
|
698
|
+
cont_var = define_continuous(:permissive, [var])[0]
|
699
|
+
end
|
685
700
|
|
701
|
+
flow_hash[ [state, cont_var] ] ||= begin
|
686
702
|
after_commit do
|
687
703
|
## a pity to use after_commit, when "just_before_commit" would be ok
|
688
704
|
## use the defer mechanism from teja2hsif
|
@@ -692,19 +708,17 @@ module RedShift
|
|
692
708
|
"redefined with non-strict flow.", []
|
693
709
|
end
|
694
710
|
end
|
711
|
+
|
712
|
+
@flow_wrapper_hash ||= {}
|
713
|
+
@flow_wrapper_hash[ [flow.var, flow.formula] ] ||=
|
714
|
+
flow.become_generatable(self, state)
|
695
715
|
end
|
696
716
|
end
|
697
|
-
|
698
|
-
def flow_wrapper flow, state
|
699
|
-
@flow_wrapper_hash ||= {}
|
700
|
-
@flow_wrapper_hash[ [flow.var, flow.formula] ] ||=
|
701
|
-
flow.flow_wrapper(self, state)
|
702
|
-
end
|
703
717
|
|
704
718
|
def define_guard(expr)
|
705
|
-
@
|
706
|
-
@
|
707
|
-
CexprGuard.new(expr).
|
719
|
+
@guard_hash ||= {} ## could be a superhash?
|
720
|
+
@guard_hash[expr] ||=
|
721
|
+
CexprGuard.new(expr).become_generatable(self)
|
708
722
|
end
|
709
723
|
|
710
724
|
def make_guard_method_name
|
@@ -736,18 +750,25 @@ module RedShift
|
|
736
750
|
g # a proc is slower than a method when called from step_discrete
|
737
751
|
end
|
738
752
|
|
739
|
-
when Class
|
740
|
-
if g < GuardWrapper
|
741
|
-
g
|
742
|
-
else
|
743
|
-
raise "What is #{g.inspect}?"
|
744
|
-
end
|
745
|
-
|
746
753
|
when String
|
747
754
|
define_guard(g)
|
748
755
|
|
756
|
+
when CexprGuard
|
757
|
+
# already defined (shared guards)
|
758
|
+
g
|
759
|
+
|
749
760
|
else
|
750
|
-
raise "
|
761
|
+
raise "Can't define guard for #{g.class} : #{g.inspect}"
|
762
|
+
end
|
763
|
+
end
|
764
|
+
after_commit do
|
765
|
+
guards.map! do |g|
|
766
|
+
case g
|
767
|
+
when CexprGuard
|
768
|
+
g.wrapper
|
769
|
+
else
|
770
|
+
g
|
771
|
+
end
|
751
772
|
end
|
752
773
|
end
|
753
774
|
end
|
@@ -755,7 +776,8 @@ module RedShift
|
|
755
776
|
def define_syncs syncs
|
756
777
|
after_commit do
|
757
778
|
syncs.each do |sync_phase_item|
|
758
|
-
sync_phase_item.link_offset =
|
779
|
+
sync_phase_item.link_offset =
|
780
|
+
offset_of_var(sync_phase_item.link_name)
|
759
781
|
end
|
760
782
|
end
|
761
783
|
end
|
@@ -776,9 +798,9 @@ module RedShift
|
|
776
798
|
end
|
777
799
|
|
778
800
|
def define_reset(expr, type = "double")
|
779
|
-
@
|
780
|
-
@
|
781
|
-
ResetExpr.new(expr, type).
|
801
|
+
@expr_hash ||= {} ## could be a superhash?
|
802
|
+
@expr_hash[expr] ||=
|
803
|
+
ResetExpr.new(expr, type).become_generatable(self)
|
782
804
|
end
|
783
805
|
|
784
806
|
def define_resets(phase)
|
@@ -811,7 +833,7 @@ module RedShift
|
|
811
833
|
reset = define_reset(expr)
|
812
834
|
|
813
835
|
after_commit do
|
814
|
-
phase[cont_var.index] = reset.
|
836
|
+
phase[cont_var.index] = reset.wrapper
|
815
837
|
end
|
816
838
|
|
817
839
|
when Numeric
|
@@ -837,7 +859,7 @@ module RedShift
|
|
837
859
|
reset = define_reset(expr)
|
838
860
|
|
839
861
|
after_commit do
|
840
|
-
phase << [offset_of_var(var), reset.
|
862
|
+
phase << [offset_of_var(var), reset.wrapper, var]
|
841
863
|
end
|
842
864
|
|
843
865
|
when Numeric
|
@@ -864,7 +886,7 @@ module RedShift
|
|
864
886
|
reset = define_reset(expr, "ComponentShadow *")
|
865
887
|
|
866
888
|
after_commit do
|
867
|
-
phase << [offset_of_var(var), reset.
|
889
|
+
phase << [offset_of_var(var), reset.wrapper, var, type]
|
868
890
|
end
|
869
891
|
|
870
892
|
when Proc, NilClass
|
@@ -878,9 +900,9 @@ module RedShift
|
|
878
900
|
phase.each do |item|
|
879
901
|
case item.value
|
880
902
|
when ExprEventValue
|
881
|
-
|
903
|
+
reset = define_reset(item.value)
|
882
904
|
after_commit do
|
883
|
-
item.value =
|
905
|
+
item.value = reset.wrapper
|
884
906
|
end
|
885
907
|
end
|
886
908
|
end
|
@@ -1054,6 +1076,78 @@ module RedShift
|
|
1054
1076
|
end
|
1055
1077
|
## end # if need connect
|
1056
1078
|
|
1079
|
+
library.source_file.declare :INIT_WRAPPER_DEFS => %{
|
1080
|
+
#define ALGEBRAIC 1
|
1081
|
+
#define NONALGEBRAIC 0
|
1082
|
+
#define STRICT 1
|
1083
|
+
#define NONSTRICT 0
|
1084
|
+
}
|
1085
|
+
|
1086
|
+
library.define(:s_init_flow).instance_eval do
|
1087
|
+
arguments "void (*fn)()", "char *fname", "char *inspect_str", "int alg"
|
1088
|
+
|
1089
|
+
fw_ssn = Component::FlowWrapper.shadow_struct_name
|
1090
|
+
fw_cname = library.declare_class Component::FlowWrapper
|
1091
|
+
comp_cname = library.declare_class Component
|
1092
|
+
id_new = library.declare_symbol :new
|
1093
|
+
id_store_wrapper = library.declare_symbol :store_wrapper
|
1094
|
+
|
1095
|
+
body %{\
|
1096
|
+
#{fw_ssn} *fw_shadow;
|
1097
|
+
VALUE fw;
|
1098
|
+
|
1099
|
+
fw = rb_funcall(#{fw_cname}, #{id_new}, 1, rb_str_new2(inspect_str));
|
1100
|
+
Data_Get_Struct(fw, #{fw_ssn}, fw_shadow);
|
1101
|
+
fw_shadow->flow = fn;
|
1102
|
+
fw_shadow->algebraic = alg;
|
1103
|
+
rb_funcall(#{comp_cname}, #{id_store_wrapper}, 2,
|
1104
|
+
rb_str_new2(fname), fw);
|
1105
|
+
}.rstrip
|
1106
|
+
end
|
1107
|
+
|
1108
|
+
library.define(:s_init_guard).instance_eval do
|
1109
|
+
arguments "void (*fn)()", "char *fname", "char *inspect_str", "int strict"
|
1110
|
+
|
1111
|
+
gw_ssn = Component::GuardWrapper.shadow_struct_name
|
1112
|
+
gw_cname = library.declare_class Component::GuardWrapper
|
1113
|
+
comp_cname = library.declare_class Component
|
1114
|
+
id_new = library.declare_symbol :new
|
1115
|
+
id_store_wrapper = library.declare_symbol :store_wrapper
|
1116
|
+
|
1117
|
+
body %{\
|
1118
|
+
#{gw_ssn} *gw_shadow;
|
1119
|
+
VALUE gw;
|
1120
|
+
|
1121
|
+
gw = rb_funcall(#{gw_cname}, #{id_new}, 1, rb_str_new2(inspect_str));
|
1122
|
+
Data_Get_Struct(gw, #{gw_ssn}, gw_shadow);
|
1123
|
+
gw_shadow->guard = fn;
|
1124
|
+
gw_shadow->strict = strict;
|
1125
|
+
rb_funcall(#{comp_cname}, #{id_store_wrapper}, 2,
|
1126
|
+
rb_str_new2(fname), gw);
|
1127
|
+
}.rstrip
|
1128
|
+
end
|
1129
|
+
|
1130
|
+
library.define(:s_init_expr).instance_eval do
|
1131
|
+
arguments "void (*fn)()", "char *fname", "char *inspect_str"
|
1132
|
+
|
1133
|
+
ew_ssn = Component::ExprWrapper.shadow_struct_name
|
1134
|
+
ew_cname = library.declare_class Component::ExprWrapper
|
1135
|
+
comp_cname = library.declare_class Component
|
1136
|
+
id_new = library.declare_symbol :new
|
1137
|
+
id_store_wrapper = library.declare_symbol :store_wrapper
|
1138
|
+
|
1139
|
+
body %{\
|
1140
|
+
#{ew_ssn} *ew_shadow;
|
1141
|
+
VALUE ew;
|
1142
|
+
|
1143
|
+
ew = rb_funcall(#{ew_cname}, #{id_new}, 1, rb_str_new2(inspect_str));
|
1144
|
+
Data_Get_Struct(ew, #{ew_ssn}, ew_shadow);
|
1145
|
+
ew_shadow->expr = fn;
|
1146
|
+
rb_funcall(#{comp_cname}, #{id_store_wrapper}, 2,
|
1147
|
+
rb_str_new2(fname), ew);
|
1148
|
+
}.rstrip
|
1149
|
+
end
|
1150
|
+
|
1057
1151
|
define_c_method :clear_ck_strict do
|
1058
1152
|
declare :locals => %{
|
1059
1153
|
ContVar *vars;
|
@@ -1100,9 +1194,9 @@ module RedShift
|
|
1100
1194
|
|
1101
1195
|
## can this go in shadow_library_source_file instead of library?
|
1102
1196
|
library.define(:rs_update_cache).instance_eval do
|
1103
|
-
flow_wrapper_type = Component::FlowWrapper.
|
1197
|
+
flow_wrapper_type = Component::FlowWrapper.shadow_struct_name
|
1104
1198
|
scope :extern ## might be better to keep static and put in world.c
|
1105
|
-
arguments "struct #{Component.
|
1199
|
+
arguments "struct #{Component.shadow_struct_name} *shadow"
|
1106
1200
|
declare :locals => %{
|
1107
1201
|
#{flow_wrapper_type} *flow_wrapper;
|
1108
1202
|
|
@@ -1160,7 +1254,7 @@ module RedShift
|
|
1160
1254
|
has_diff = 1;
|
1161
1255
|
if (var->flow && var->algebraic && var->strict &&
|
1162
1256
|
var->d_tick > 0) { //# did anyone rely on the strictness?
|
1163
|
-
var->
|
1257
|
+
var->value[1] = var->value[0];
|
1164
1258
|
var->ck_strict = 1;
|
1165
1259
|
}
|
1166
1260
|
else {
|
@@ -1282,7 +1376,7 @@ module RedShift
|
|
1282
1376
|
var->d_tick = sh->world->d_tick;
|
1283
1377
|
}
|
1284
1378
|
|
1285
|
-
result =
|
1379
|
+
result = var->value[sh->world->rk_level];
|
1286
1380
|
break;
|
1287
1381
|
}
|
1288
1382
|
|
@@ -1292,7 +1386,7 @@ module RedShift
|
|
1292
1386
|
|
1293
1387
|
case INPUT_INP_VAR:
|
1294
1388
|
tgt = (struct target *)(tgt->psh + tgt->offset);
|
1295
|
-
if (depth++ >
|
1389
|
+
if (depth++ > sh->world->input_depth_limit) {
|
1296
1390
|
size_t offset = psrc_comp - (char *)shadow;
|
1297
1391
|
VALUE str = rb_funcall(shadow->self,
|
1298
1392
|
#{declare_symbol :get_varname_by_offset}, 1, INT2FIX(offset));
|