redshift 1.3.22 → 1.3.23

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.
Files changed (40) hide show
  1. data/.bnsignore +27 -0
  2. data/RELEASE-NOTES +6 -0
  3. data/bench/aug17-ruby19.bench +86 -0
  4. data/bench/aug17.bench +86 -0
  5. data/bench/aug7.bench +86 -0
  6. data/bench/bench +4 -1
  7. data/bench/prof.html +0 -0
  8. data/ext/redshift/buffer/buffer.c +3 -1
  9. data/ext/redshift/dvector/dvector.c +236 -0
  10. data/ext/redshift/dvector/dvector.h +36 -0
  11. data/ext/redshift/dvector/dvector.rb +33 -0
  12. data/ext/redshift/dvector/extconf.rb +2 -0
  13. data/lib/redshift/redshift.rb +1 -1
  14. data/lib/redshift/target/c/component-gen.rb +17 -23
  15. data/lib/redshift/target/c/flow-gen.rb +2 -2
  16. data/lib/redshift/target/c/flow/algebraic.rb +1 -1
  17. data/lib/redshift/target/c/flow/delay.rb +1 -1
  18. data/lib/redshift/target/c/flow/derivative.rb +1 -1
  19. data/lib/redshift/target/c/flow/rk4.rb +1 -1
  20. data/lib/redshift/target/c/library.rb +5 -0
  21. data/lib/redshift/target/c/world-gen.rb +130 -127
  22. data/lib/redshift/util/isaac.rb +2 -2
  23. data/lib/redshift/util/random.rb +1 -1
  24. data/lib/redshift/world.rb +11 -6
  25. data/test/test_discrete.rb +1 -1
  26. data/test/test_discrete_isolated.rb +1 -1
  27. data/test/test_dvector.rb +110 -0
  28. data/test/test_flow.rb +1 -1
  29. data/test/test_flow_link.rb +1 -1
  30. data/test/test_flow_sub.rb +1 -1
  31. data/test/test_flow_trans.rb +3 -3
  32. data/test/test_inherit_event.rb +1 -1
  33. data/test/test_inherit_flow.rb +1 -1
  34. data/test/test_inherit_link.rb +1 -1
  35. data/test/test_inherit_state.rb +1 -1
  36. data/test/test_inherit_transition.rb +1 -1
  37. data/test/test_setup.rb +1 -1
  38. data/test/test_strict_continuity.rb +1 -1
  39. data/test/test_world.rb +4 -4
  40. metadata +22 -8
@@ -0,0 +1,36 @@
1
+ #ifndef dvector_h
2
+ #define dvector_h
3
+
4
+ #include <ruby.h>
5
+
6
+ typedef struct {
7
+ long len;
8
+ long capa;
9
+ VALUE *ptr;
10
+ } RS_DVector;
11
+
12
+ extern void rs_dv_grow(RS_DVector *dv);
13
+ extern void rs_dv_shrink(RS_DVector *dv);
14
+
15
+ inline static RS_DVector *rs_dv(VALUE obj)
16
+ {
17
+ return (RS_DVector *)DATA_PTR(obj);
18
+ }
19
+
20
+ inline static void rs_dv_push(RS_DVector *dv, VALUE val)
21
+ {
22
+ if (dv->len == dv->capa) {
23
+ rs_dv_grow(dv);
24
+ }
25
+ dv->ptr[dv->len++] = val;
26
+ }
27
+
28
+ inline static VALUE rs_dv_pop(RS_DVector *dv)
29
+ {
30
+ if (dv->len == 0) {
31
+ return Qnil;
32
+ }
33
+ return dv->ptr[--dv->len];
34
+ }
35
+
36
+ #endif
@@ -0,0 +1,33 @@
1
+ module RedShift; end
2
+
3
+ # A linear collection of objects, like Array.
4
+ #
5
+ # Intended primarily for access from C code, using the inline
6
+ # rs_dv_push() and rs_dv_pop() functions.
7
+ #
8
+ # Implements some of the same methods as Array, but not all.
9
+ #
10
+ # Like an Array, a DVector grows implicitly as elements are
11
+ # pushed. But unlike an Array, a DVector shrinks only explicitly.
12
+ # This is to minimize realloc() calls when a DVector rapidly
13
+ # grows and shrinks.
14
+
15
+ class RedShift::DVector
16
+ include Enumerable
17
+ require 'redshift/dvector/dvector.so'
18
+
19
+ def self.[](*elts)
20
+ new elts
21
+ end
22
+
23
+ def initialize(elts=nil)
24
+ push(*elts) if elts
25
+ end
26
+
27
+ def inspect; to_a.inspect; end
28
+ def to_s; to_a.to_s; end
29
+
30
+ def dup
31
+ self.class.new to_a
32
+ end
33
+ end
@@ -0,0 +1,2 @@
1
+ require 'mkmf'
2
+ create_makefile 'dvector'
@@ -70,7 +70,7 @@ end
70
70
  module RedShift
71
71
  include Math
72
72
 
73
- VERSION = '1.3.22'
73
+ VERSION = '1.3.23'
74
74
 
75
75
  Infinity = Math::Infinity
76
76
 
@@ -4,8 +4,6 @@ module RedShift
4
4
  # just so we can call shadow_struct_name on it
5
5
  end
6
6
 
7
- HAVE_DEFINE_METHOD = Module.private_instance_methods.include?("define_method")
8
-
9
7
  class Component
10
8
  include CShadow
11
9
  shadow_library RedShift.library
@@ -738,17 +736,13 @@ module RedShift
738
736
  g
739
737
 
740
738
  when Proc
741
- if HAVE_DEFINE_METHOD
742
- meth = Component.make_guard_method_name
743
- class_eval do
744
- define_method(meth, &g)
745
- end
746
- ## Currently, methods defined with define_method are a little
747
- ## slower to invoke in ruby.
748
- meth
749
- else
750
- g # a proc is slower than a method when called from step_discrete
739
+ meth = Component.make_guard_method_name
740
+ class_eval do
741
+ define_method(meth, &g)
751
742
  end
743
+ ## Currently, methods defined with define_method are a little
744
+ ## slower to invoke in ruby.
745
+ meth
752
746
 
753
747
  when String
754
748
  define_guard(g)
@@ -944,8 +938,8 @@ module RedShift
944
938
  idx_ary = rb_funcall(shadow->cont_state->self, #{svi}, 0);
945
939
  Check_Type(idx_ary, T_ARRAY); //## debug only
946
940
 
947
- count = RARRAY(idx_ary)->len;
948
- indexes = RARRAY(idx_ary)->ptr;
941
+ count = RARRAY_LEN(idx_ary);
942
+ indexes = RARRAY_PTR(idx_ary);
949
943
 
950
944
  for (i = 0; i < count; i++) {
951
945
  idx = NUM2INT(indexes[i]);
@@ -1084,7 +1078,7 @@ module RedShift
1084
1078
  }
1085
1079
 
1086
1080
  library.define(:s_init_flow).instance_eval do
1087
- arguments "void (*fn)()", "char *fname", "char *inspect_str", "int alg"
1081
+ arguments "void (*fn)()", "const char *fname", "const char *inspect_str", "int alg"
1088
1082
 
1089
1083
  fw_ssn = Component::FlowWrapper.shadow_struct_name
1090
1084
  fw_cname = library.declare_class Component::FlowWrapper
@@ -1106,7 +1100,7 @@ module RedShift
1106
1100
  end
1107
1101
 
1108
1102
  library.define(:s_init_guard).instance_eval do
1109
- arguments "void (*fn)()", "char *fname", "char *inspect_str", "int strict"
1103
+ arguments "int (*fn)()", "const char *fname", "const char *inspect_str", "int strict"
1110
1104
 
1111
1105
  gw_ssn = Component::GuardWrapper.shadow_struct_name
1112
1106
  gw_cname = library.declare_class Component::GuardWrapper
@@ -1128,7 +1122,7 @@ module RedShift
1128
1122
  end
1129
1123
 
1130
1124
  library.define(:s_init_expr).instance_eval do
1131
- arguments "void (*fn)()", "char *fname", "char *inspect_str"
1125
+ arguments "double (*fn)()", "const char *fname", "const char *inspect_str"
1132
1126
 
1133
1127
  ew_ssn = Component::ExprWrapper.shadow_struct_name
1134
1128
  ew_cname = library.declare_class Component::ExprWrapper
@@ -1210,10 +1204,11 @@ module RedShift
1210
1204
  long count;
1211
1205
  VALUE *flows;
1212
1206
  int has_diff;
1213
- struct RArray *ary;
1214
1207
  int flags;
1215
1208
  }.tabto(0)
1216
1209
 
1210
+ include("dvector/dvector.h")
1211
+
1217
1212
  body %{
1218
1213
  var_count = shadow->var_count;
1219
1214
  vars = (ContVar *)&FIRST_CONT_VAR(shadow);
@@ -1222,8 +1217,7 @@ module RedShift
1222
1217
  shadow->outgoing = rb_funcall(shadow->self,
1223
1218
  #{declare_symbol :outgoing_transition_data}, 0);
1224
1219
 
1225
- ary = RARRAY(shadow->outgoing);
1226
- flags = FIX2INT(ary->ptr[ary->len-1]);
1220
+ flags = FIX2INT(RARRAY_PTR(shadow->outgoing)[RARRAY_LEN(shadow->outgoing)-1]);
1227
1221
  shadow->strict = flags & 0x01;
1228
1222
  shadow->sleepable = !!(flags & 0x02);
1229
1223
 
@@ -1236,8 +1230,8 @@ module RedShift
1236
1230
 
1237
1231
  if (flow_array != Qnil) {
1238
1232
  #{"Check_Type(flow_array, T_ARRAY);\n" if $REDSHIFT_DEBUG}
1239
- count = RARRAY(flow_array)->len;
1240
- flows = RARRAY(flow_array)->ptr;
1233
+ count = RARRAY_LEN(flow_array);
1234
+ flows = RARRAY_PTR(flow_array);
1241
1235
 
1242
1236
  if (count > var_count)
1243
1237
  rs_raise(#{declare_class IndexError}, shadow->self,
@@ -1287,7 +1281,7 @@ module RedShift
1287
1281
  if (has_diff && !shadow->has_diff) {
1288
1282
  if (!shadow->diff_list) {
1289
1283
  if (shadow->world->diff_list) { //# 0 if loading
1290
- rb_ary_push(shadow->world->diff_list, shadow->self);
1284
+ rs_dv_push(rs_dv(shadow->world->diff_list), shadow->self);
1291
1285
  }
1292
1286
  shadow->diff_list = 1;
1293
1287
  }
@@ -110,7 +110,7 @@ module RedShift; class Flow
110
110
  VALUE event_values, event_val;
111
111
  event_values = shadow->event_values;
112
112
  assert(event_values != Qnil);
113
- event_val = RARRAY(event_values)->ptr[#{event_idx}];
113
+ event_val = RARRAY_PTR(event_values)[#{event_idx}];
114
114
  #{var_cname} = NUM2DBL(event_val);
115
115
  }
116
116
 
@@ -311,7 +311,7 @@ module RedShift; class Flow
311
311
  rs_raise(#{exc_nil}, ct->shadow->self, #{msg_nil.inspect});
312
312
  event_values = ct->#{link_cname}->event_values;
313
313
  assert(event_values != Qnil);
314
- event_val = RARRAY(event_values)->ptr[#{event_idx}];
314
+ event_val = RARRAY_PTR(event_values)[#{event_idx}];
315
315
  return NUM2DBL(event_val);
316
316
  }
317
317
  }
@@ -65,7 +65,7 @@ module RedShift; class AlgebraicFlow
65
65
 
66
66
  default:
67
67
  rb_raise(#{declare_class RuntimeError},
68
- "Bad rk_level, %d!", shadow->world->rk_level);
68
+ "Bad rk_level, %ld!", shadow->world->rk_level);
69
69
  }
70
70
 
71
71
  shadow->world->alg_nest--;
@@ -153,7 +153,7 @@ module RedShift; class DelayFlow
153
153
 
154
154
  default:
155
155
  rb_raise(#{declare_class RuntimeError},
156
- "Bad rk_level, %d!", shadow->world->rk_level);
156
+ "Bad rk_level, %ld!", shadow->world->rk_level);
157
157
  }
158
158
 
159
159
  shadow->world->rk_level++;
@@ -84,7 +84,7 @@ module RedShift; class DerivativeFlow
84
84
 
85
85
  default:
86
86
  rb_raise(#{declare_class RuntimeError},
87
- "Bad rk_level, %d!", shadow->world->rk_level);
87
+ "Bad rk_level, %ld!", shadow->world->rk_level);
88
88
  }
89
89
 
90
90
  shadow->world->rk_level++;
@@ -64,7 +64,7 @@ module RedShift; class RK4DifferentialFlow
64
64
 
65
65
  default:
66
66
  rb_raise(#{declare_class RuntimeError},
67
- "Bad rk_level, %d!", shadow->world->rk_level);
67
+ "Bad rk_level, %ld!", shadow->world->rk_level);
68
68
  }
69
69
 
70
70
  shadow->world->rk_level++;
@@ -22,9 +22,14 @@ module RedShift
22
22
  end
23
23
 
24
24
  include_file.include '<math.h>'
25
+
26
+ base = File.expand_path("../../../..", __FILE__)
27
+ ext_rs = File.join(base, "ext/redshift")
28
+ include_dirs << ext_rs
25
29
  end
26
30
 
27
31
  # Call this to link with external libraries. See examples/external-lib.rb.
32
+ # Note also include_dirs array.
28
33
  def link_with *libs
29
34
  (@link_libs ||= []) << libs
30
35
  end
@@ -5,14 +5,15 @@ class World
5
5
  shadow_library RedShift.library
6
6
  shadow_library_file "World"
7
7
  shadow_library_source_file.include(Component.shadow_library_include_file)
8
+ shadow_library_source_file.include("dvector/dvector.h")
8
9
 
9
10
  shadow_library_include_file.declare :step_discrete_macros => '
10
11
  #define INT2BOOL(i) (i ? Qtrue : Qfalse)
11
12
 
12
13
  #define SWAP_VALUE(v, w) {VALUE ___tmp = v; v = w; w = ___tmp;}
13
14
 
14
- #define EACH_COMP_DO(lc) \\
15
- for (list = RARRAY(lc), list_i = list->len - 1; \\
15
+ #define EACH_COMP_DO(lc) \\
16
+ for (list = rs_dv(lc), list_i = list->len - 1; \\
16
17
  list_i >= 0 && ( \\
17
18
  comp = list->ptr[list_i], \\
18
19
  comp_shdw = get_shadow(comp), \\
@@ -23,7 +24,7 @@ class World
23
24
  '.tabto(0)
24
25
  # Note: EACH_COMP_DO(lc) block may use move_comp and remove_comp
25
26
  # but it should (re)move none or all. Must have declarations for comp
26
- # comp_shdw, list, and list_i in scope.
27
+ # comp_shdw, list, and list_i in scope. lc must be a DVector.
27
28
 
28
29
  shadow_library_include_file.declare :cv_cache_entry => %{
29
30
  typedef struct {
@@ -60,19 +61,19 @@ class World
60
61
  sub.shadow_library_file file_name
61
62
  end
62
63
 
63
- shadow_attr_accessor :curr_A => Array
64
- shadow_attr_accessor :curr_P => Array
65
- shadow_attr_accessor :curr_CR => Array
66
- shadow_attr_accessor :curr_S => Array
67
- shadow_attr_accessor :next_S => Array
68
- shadow_attr_accessor :curr_T => Array
69
- shadow_attr_accessor :active_E => Array
70
- shadow_attr_accessor :prev_active_E => Array
71
- shadow_attr_accessor :awake => Array
72
- shadow_attr_accessor :prev_awake => Array
73
- shadow_attr_accessor :strict_sleep => Array
74
- shadow_attr_accessor :inert => Array
75
- shadow_attr_accessor :diff_list => Array
64
+ shadow_attr_accessor :curr_A => DVector
65
+ shadow_attr_accessor :curr_P => DVector
66
+ shadow_attr_accessor :curr_CR => DVector
67
+ shadow_attr_accessor :curr_S => DVector
68
+ shadow_attr_accessor :next_S => DVector
69
+ shadow_attr_accessor :curr_T => DVector
70
+ shadow_attr_accessor :active_E => DVector
71
+ shadow_attr_accessor :prev_active_E => DVector
72
+ shadow_attr_accessor :awake => DVector
73
+ shadow_attr_accessor :prev_awake => DVector
74
+ shadow_attr_accessor :strict_sleep => DVector
75
+ shadow_attr_accessor :inert => DVector
76
+ shadow_attr_accessor :diff_list => DVector
76
77
  shadow_attr_accessor :queue_sleep => Hash
77
78
  protected \
78
79
  :curr_A, :curr_P, :curr_CR, :curr_T,
@@ -191,7 +192,7 @@ class World
191
192
 
192
193
  define_c_method :step_continuous do
193
194
  declare :locals => %{
194
- VALUE comp_rb_ary[2], *comp_ary;
195
+ VALUE comp_dvector[2], *comp_ary;
195
196
  long len;
196
197
  long var_count;
197
198
  ContVar *var, *end_var;
@@ -199,11 +200,11 @@ class World
199
200
  ComponentShadow *comp_shdw;
200
201
  }.tabto(0)
201
202
  body %{
202
- comp_rb_ary[0] = shadow->awake;
203
- comp_rb_ary[1] = shadow->inert;
203
+ comp_dvector[0] = shadow->awake;
204
+ comp_dvector[1] = shadow->inert;
204
205
  for (li = 0; li < 2; li++) {
205
- len = RARRAY(comp_rb_ary[li])->len;
206
- comp_ary = RARRAY(comp_rb_ary[li])->ptr;
206
+ len = rs_dv(comp_dvector[li])->len;
207
+ comp_ary = rs_dv(comp_dvector[li])->ptr;
207
208
  for (ci = 0; ci < len; ci++) {
208
209
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
209
210
  var_count = comp_shdw->var_count;
@@ -221,8 +222,8 @@ class World
221
222
  }
222
223
 
223
224
  for (shadow->rk_level = 1; shadow->rk_level <= 3; shadow->rk_level++) {
224
- len = RARRAY(shadow->diff_list)->len;
225
- comp_ary = RARRAY(shadow->diff_list)->ptr;
225
+ len = rs_dv(shadow->diff_list)->len;
226
+ comp_ary = rs_dv(shadow->diff_list)->ptr;
226
227
  for (ci = 0; ci < len; ci++) {
227
228
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
228
229
 
@@ -231,7 +232,7 @@ class World
231
232
  comp_ary[ci] = comp_ary[len-1];
232
233
  ci--;
233
234
  }
234
- len = RARRAY(shadow->diff_list)->len = len-1;
235
+ len = rs_dv(shadow->diff_list)->len = len-1;
235
236
  comp_shdw->diff_list = 0;
236
237
  }
237
238
  else {
@@ -252,8 +253,8 @@ class World
252
253
 
253
254
  shadow->rk_level = 4;
254
255
  for (li = 0; li < 2; li++) {
255
- len = RARRAY(comp_rb_ary[li])->len;
256
- comp_ary = RARRAY(comp_rb_ary[li])->ptr;
256
+ len = rs_dv(comp_dvector[li])->len;
257
+ comp_ary = rs_dv(comp_dvector[li])->ptr;
257
258
  for (ci = 0; ci < len; ci++) {
258
259
  Data_Get_Struct(comp_ary[ci], ComponentShadow, comp_shdw);
259
260
  var_count = comp_shdw->var_count;
@@ -310,84 +311,80 @@ class World
310
311
  VALUE *ptr;
311
312
  long len;
312
313
  long i;
313
- struct RArray *list;
314
+ RS_DVector *list;
314
315
  int list_i;
315
316
  int did_reset;
316
317
  }.tabto(0)
317
318
 
318
319
  insteval_proc = declare_symbol :insteval_proc
319
- capa = RUBY_VERSION.to_f >= 1.7 ? "aux.capa" : "capa"
320
320
  epi = Component::EventPhaseItem
321
321
  spi = Component::SyncPhaseItem
322
322
 
323
323
  parent.declare :step_discrete_subs => %{
324
324
  inline static VALUE cur_syncs(ComponentShadow *comp_shdw)
325
325
  {
326
- VALUE syncs = RARRAY(comp_shdw->trans)->ptr[#{Transition::S_IDX}];
326
+ VALUE syncs = RARRAY_PTR(comp_shdw->trans)[#{Transition::S_IDX}];
327
327
  assert(syncs == Qnil || RBASIC(syncs)->klass == SyncClass);
328
328
  return syncs;
329
329
  }
330
330
  inline static VALUE cur_actions(ComponentShadow *comp_shdw)
331
331
  {
332
- VALUE actions = RARRAY(comp_shdw->trans)->ptr[#{Transition::A_IDX}];
332
+ VALUE actions = RARRAY_PTR(comp_shdw->trans)[#{Transition::A_IDX}];
333
333
  assert(actions == Qnil || RBASIC(actions)->klass == ActionClass);
334
334
  return actions;
335
335
  }
336
336
  inline static VALUE cur_posts(ComponentShadow *comp_shdw)
337
337
  {
338
- VALUE posts = RARRAY(comp_shdw->trans)->ptr[#{Transition::P_IDX}];
338
+ VALUE posts = RARRAY_PTR(comp_shdw->trans)[#{Transition::P_IDX}];
339
339
  assert(posts == Qnil || RBASIC(posts)->klass == PostClass);
340
340
  return posts;
341
341
  }
342
342
  inline static VALUE cur_events(ComponentShadow *comp_shdw)
343
343
  {
344
- VALUE events = RARRAY(comp_shdw->trans)->ptr[#{Transition::E_IDX}];
344
+ VALUE events = RARRAY_PTR(comp_shdw->trans)[#{Transition::E_IDX}];
345
345
  assert(events == Qnil || RBASIC(events)->klass == EventClass);
346
346
  return events;
347
347
  }
348
348
  inline static VALUE cur_resets(ComponentShadow *comp_shdw)
349
349
  {
350
- VALUE resets = RARRAY(comp_shdw->trans)->ptr[#{Transition::R_IDX}];
350
+ VALUE resets = RARRAY_PTR(comp_shdw->trans)[#{Transition::R_IDX}];
351
351
  assert(resets == Qnil || RBASIC(resets)->klass == ResetClass);
352
352
  return resets;
353
353
  }
354
354
  inline static VALUE cur_connects(ComponentShadow *comp_shdw)
355
355
  {
356
- VALUE connects = RARRAY(comp_shdw->trans)->ptr[#{Transition::C_IDX}];
356
+ VALUE connects = RARRAY_PTR(comp_shdw->trans)[#{Transition::C_IDX}];
357
357
  assert(connects == Qnil || RBASIC(connects)->klass == ConnectClass);
358
358
  return connects;
359
359
  }
360
360
  inline static void move_comp(VALUE comp, VALUE list, VALUE next_list)
361
361
  {
362
- struct RArray *nl = RARRAY(next_list);
363
- assert(RARRAY(list)->ptr[RARRAY(list)->len-1] == comp);
364
- if (nl->len == nl->#{capa})
365
- rb_ary_store(next_list, nl->len, comp);
366
- else
367
- nl->ptr[nl->len++] = comp;
368
- --RARRAY(list)->len;
362
+ RS_DVector *dv = rs_dv(next_list);
363
+ assert(rs_dv(list)->ptr[rs_dv(list)->len-1] == comp);
364
+ rs_dv_push(dv, comp);
365
+ --rs_dv(list)->len;
369
366
  }
370
367
  inline static void move_comp_to_hash(VALUE comp, VALUE list, VALUE hash)
371
368
  {
372
- struct RArray *l = RARRAY(list);
373
- assert(l->ptr[l->len-1] == comp);
369
+ RS_DVector *dv = rs_dv(list);
370
+ assert(dv->ptr[dv->len-1] == comp);
374
371
  rb_hash_aset(hash, comp, Qtrue);
375
- --l->len;
372
+ --dv->len;
376
373
  }
377
374
  inline static void move_all_comps(VALUE list, VALUE next_list)
378
375
  { //## this could be faster using memcpy
379
- struct RArray *l = RARRAY(list);
380
- while (l->len)
381
- move_comp(l->ptr[l->len-1], list, next_list);
376
+ RS_DVector *dv = rs_dv(list);
377
+ while (dv->len)
378
+ move_comp(dv->ptr[dv->len-1], list, next_list);
382
379
  }
383
380
  inline static void remove_comp(VALUE comp, VALUE list,
384
381
  #{World.shadow_struct_name} *shadow)
385
382
  {
386
383
  ComponentShadow *comp_shdw = get_shadow(comp);
387
- assert(RARRAY(list)->ptr[RARRAY(list)->len-1] == comp);
384
+ assert(rs_dv(list)->ptr[rs_dv(list)->len-1] == comp);
388
385
  assert(comp_shdw->world == shadow);
389
386
  comp_shdw->world = 0;
390
- --RARRAY(list)->len;
387
+ --rs_dv(list)->len;
391
388
  //%% hook_remove_comp(comp_shdw->self);
392
389
  }
393
390
  inline static double eval_expr(VALUE comp, VALUE expr)
@@ -425,8 +422,8 @@ class World
425
422
  int i;
426
423
  VALUE kl;
427
424
  assert(BUILTIN_TYPE(guards) == T_ARRAY);
428
- for (i = 0; i < RARRAY(guards)->len; i++) {
429
- VALUE guard = RARRAY(guards)->ptr[i];
425
+ for (i = 0; i < RARRAY_LEN(guards); i++) {
426
+ VALUE guard = RARRAY_PTR(guards)[i];
430
427
 
431
428
  if (SYMBOL_P(guard)) {
432
429
  if (!RTEST(rb_funcall(comp, SYM2ID(guard), 0)))
@@ -449,8 +446,8 @@ class World
449
446
  case T_ARRAY:
450
447
  kl = RBASIC(guard)->klass;
451
448
  if (kl == QMatchClass) {
452
- int len = RARRAY(guard)->len;
453
- VALUE *ptr = RARRAY(guard)->ptr;
449
+ int len = RARRAY_LEN(guard);
450
+ VALUE *ptr = RARRAY_PTR(guard);
454
451
  assert(len > 0);
455
452
  VALUE queue_name = ptr[0];
456
453
  VALUE queue = rb_funcall(comp, SYM2ID(queue_name), 0);
@@ -480,11 +477,11 @@ class World
480
477
  VALUE syncs = cur_syncs(comp_shdw);
481
478
  assert(RTEST(syncs));
482
479
 
483
- for (i = RARRAY(syncs)->len - 1; i >= 0; i--) {
484
- VALUE sync = RARRAY(syncs)->ptr[i];
485
- assert(RARRAY(sync)->len == 3);
486
- int link_offset = FIX2INT(RARRAY(sync)->ptr[#{spi::LINK_OFFSET_IDX}]);
487
- VALUE event = RARRAY(sync)->ptr[#{spi::EVENT_IDX}];
480
+ for (i = RARRAY_LEN(syncs) - 1; i >= 0; i--) {
481
+ VALUE sync = RARRAY_PTR(syncs)[i];
482
+ assert(RARRAY_LEN(sync) == 3);
483
+ int link_offset = FIX2INT(RARRAY_PTR(sync)[#{spi::LINK_OFFSET_IDX}]);
484
+ VALUE event = RARRAY_PTR(sync)[#{spi::EVENT_IDX}];
488
485
  ComponentShadow *link_shdw =
489
486
  *(ComponentShadow **)(((char *)comp_shdw) + link_offset);
490
487
 
@@ -496,11 +493,11 @@ class World
496
493
  int found = 0;
497
494
  VALUE link_events = cur_events(link_shdw);
498
495
  if (RTEST(link_events)) {
499
- VALUE *ptr = RARRAY(link_events)->ptr;
500
- long len = RARRAY(link_events)->len;
496
+ VALUE *ptr = RARRAY_PTR(link_events);
497
+ long len = RARRAY_LEN(link_events);
501
498
 
502
499
  for (j = len; j > 0; j--, ptr++) {
503
- VALUE link_event = RARRAY(*ptr)->ptr[#{epi::E_IDX}];
500
+ VALUE link_event = RARRAY_PTR(*ptr)[#{epi::E_IDX}];
504
501
  if (link_event == event) {
505
502
  found = 1;
506
503
  break;
@@ -525,14 +522,14 @@ class World
525
522
  int has_events = RTEST(events);
526
523
 
527
524
  if (has_events) {
528
- VALUE *ptr = RARRAY(events)->ptr;
529
- long len = RARRAY(events)->len;
525
+ VALUE *ptr = RARRAY_PTR(events);
526
+ long len = RARRAY_LEN(events);
530
527
  int i;
531
528
  VALUE comp = comp_shdw->self;
532
529
 
533
530
  for (i = len; i > 0; i--, ptr++) {
534
- int event_idx = FIX2INT(RARRAY(*ptr)->ptr[#{epi::I_IDX}]);
535
- VALUE event_val = RARRAY(*ptr)->ptr[#{epi::V_IDX}];
531
+ int event_idx = FIX2INT(RARRAY_PTR(*ptr)[#{epi::I_IDX}]);
532
+ VALUE event_val = RARRAY_PTR(*ptr)[#{epi::V_IDX}];
536
533
 
537
534
  //## maybe this distinction should be made clear in the array
538
535
  //## itself, with a numeric switch, say.
@@ -542,9 +539,9 @@ class World
542
539
  else if (rb_obj_is_kind_of(event_val, ExprWrapperClass))
543
540
  event_val = rb_float_new(eval_expr(comp, event_val));
544
541
 
545
- //%% hook_eval_event(comp, RARRAY(*ptr)->ptr[#{epi::E_IDX}],
542
+ //%% hook_eval_event(comp, RARRAY_PTR(*ptr)[#{epi::E_IDX}],
546
543
  //%% event_val);
547
- RARRAY(comp_shdw->next_event_values)->ptr[event_idx] = event_val;
544
+ RARRAY_PTR(comp_shdw->next_event_values)[event_idx] = event_val;
548
545
  }
549
546
  }
550
547
 
@@ -711,12 +708,12 @@ class World
711
708
  if (!RTEST(resets))
712
709
  return 0;
713
710
 
714
- cont_resets = RARRAY(resets)->ptr[0];
711
+ cont_resets = RARRAY_PTR(resets)[0];
715
712
  has_cont_resets = RTEST(cont_resets);
716
713
 
717
714
  if (has_cont_resets) {
718
- VALUE *ptr = RARRAY(cont_resets)->ptr;
719
- long len = RARRAY(cont_resets)->len;
715
+ VALUE *ptr = RARRAY_PTR(cont_resets);
716
+ long len = RARRAY_LEN(cont_resets);
720
717
  int i;
721
718
  VALUE comp = comp_shdw->self;
722
719
  ContVar *var = (ContVar *)&FIRST_CONT_VAR(comp_shdw);
@@ -724,6 +721,7 @@ class World
724
721
 
725
722
  for (i = 0; i < len; i++, var++, ptr++) {
726
723
  VALUE reset = *ptr;
724
+ VALUE class_name;
727
725
  if (reset == Qnil) {
728
726
  var->reset = 0;
729
727
  }
@@ -736,25 +734,25 @@ class World
736
734
 
737
735
  switch(TYPE(reset)) {
738
736
  case T_FLOAT:
739
- new_value = RFLOAT(reset)->value;
737
+ new_value = RFLOAT_VALUE(reset);
740
738
  break;
741
739
  default:
742
740
  if (RBASIC(reset)->klass == rb_cProc) {
743
741
  VALUE val = rb_funcall(comp, #{insteval_proc}, 1, reset);
744
742
  switch(TYPE(val)) {
745
743
  case T_FLOAT:
746
- new_value = RFLOAT(val)->value;
744
+ new_value = RFLOAT_VALUE(val);
747
745
  break;
748
746
  case T_FIXNUM:
749
747
  new_value = FIX2INT(val);
750
748
  break;
751
749
  default:
750
+ class_name = rb_funcall(
751
+ rb_funcall(val, #{declare_symbol :class}, 0),
752
+ #{declare_symbol :to_s}, 0);
752
753
  rs_raise(#{declare_class VarTypeError}, comp,
753
754
  "tried to reset cont var with %s.",
754
- STR2CSTR(rb_funcall(
755
- rb_funcall(val, #{declare_symbol :class}, 0),
756
- #{declare_symbol :to_s},
757
- 0))
755
+ StringValuePtr(class_name)
758
756
  );
759
757
  }
760
758
  }
@@ -789,25 +787,25 @@ class World
789
787
  if (!RTEST(resets))
790
788
  return 0;
791
789
 
792
- const_resets = RARRAY(resets)->ptr[1];
793
- link_resets = RARRAY(resets)->ptr[2];
790
+ const_resets = RARRAY_PTR(resets)[1];
791
+ link_resets = RARRAY_PTR(resets)[2];
794
792
  has_const_resets = RTEST(const_resets);
795
793
  has_link_resets = RTEST(link_resets);
796
794
  comp = comp_shdw->self;
797
795
 
798
796
  if (has_const_resets) {
799
- VALUE *ptr = RARRAY(const_resets)->ptr;
800
- long len = RARRAY(const_resets)->len;
797
+ VALUE *ptr = RARRAY_PTR(const_resets);
798
+ long len = RARRAY_LEN(const_resets);
801
799
 
802
800
  for (i = 0; i < len; i++) {
803
801
  VALUE pair = ptr[i];
804
- int offset = NUM2INT(RARRAY(pair)->ptr[0]);
805
- VALUE reset = RARRAY(pair)->ptr[1];
802
+ int offset = NUM2INT(RARRAY_PTR(pair)[0]);
803
+ VALUE reset = RARRAY_PTR(pair)[1];
806
804
  double new_value;
807
805
 
808
806
  switch(TYPE(reset)) {
809
807
  case T_FLOAT:
810
- new_value = RFLOAT(reset)->value;
808
+ new_value = RFLOAT_VALUE(reset);
811
809
  break;
812
810
  default:
813
811
  if (RBASIC(reset)->klass == rb_cProc)
@@ -818,7 +816,7 @@ class World
818
816
  }
819
817
 
820
818
  //%% hook_eval_reset_constant(comp,
821
- //%% RARRAY(pair)->ptr[2], rb_float_new(new_value));
819
+ //%% RARRAY_PTR(pair)[2], rb_float_new(new_value));
822
820
  cache_new_constant_value(
823
821
  (double *)((char *)comp_shdw + offset),
824
822
  new_value, shadow);
@@ -826,13 +824,13 @@ class World
826
824
  }
827
825
 
828
826
  if (has_link_resets) {
829
- VALUE *ptr = RARRAY(link_resets)->ptr;
830
- long len = RARRAY(link_resets)->len;
827
+ VALUE *ptr = RARRAY_PTR(link_resets);
828
+ long len = RARRAY_LEN(link_resets);
831
829
 
832
830
  for (i = 0; i < len; i++) {
833
831
  VALUE pair = ptr[i];
834
- int offset = NUM2INT(RARRAY(pair)->ptr[0]);
835
- VALUE reset = RARRAY(pair)->ptr[1];
832
+ int offset = NUM2INT(RARRAY_PTR(pair)[0]);
833
+ VALUE reset = RARRAY_PTR(pair)[1];
836
834
  VALUE new_value;
837
835
 
838
836
  if (rb_obj_is_kind_of(reset, ExprWrapperClass)) {
@@ -852,19 +850,23 @@ class World
852
850
  }
853
851
 
854
852
  if (!NIL_P(new_value) &&
855
- rb_obj_is_kind_of(new_value, RARRAY(pair)->ptr[3]) != Qtrue) {
853
+ rb_obj_is_kind_of(new_value, RARRAY_PTR(pair)[3]) != Qtrue) {
856
854
  VALUE to_s = #{declare_symbol :to_s};
855
+ VALUE s1 = rb_funcall(RARRAY_PTR(pair)[2], to_s, 0);
856
+ VALUE s2 = rb_funcall(RARRAY_PTR(pair)[3], to_s, 0);
857
+ VALUE s3 = rb_funcall(
858
+ rb_funcall(new_value, #{declare_symbol :class}, 0), to_s, 0);
859
+
857
860
  rs_raise(#{declare_class LinkTypeError}, comp_shdw->self,
858
861
  "tried to reset %s, which is declared %s, with %s.",
859
- STR2CSTR(rb_funcall(RARRAY(pair)->ptr[2], to_s, 0)),
860
- STR2CSTR(rb_funcall(RARRAY(pair)->ptr[3], to_s, 0)),
861
- STR2CSTR(rb_funcall(
862
- rb_funcall(new_value, #{declare_symbol :class}, 0), to_s, 0))
862
+ StringValuePtr(s1),
863
+ StringValuePtr(s2),
864
+ StringValuePtr(s3)
863
865
  );
864
866
  }
865
867
 
866
868
  //%% hook_eval_reset_link(comp,
867
- //%% RARRAY(pair)->ptr[2], (VALUE)new_value);
869
+ //%% RARRAY_PTR(pair)[2], (VALUE)new_value);
868
870
  cache_new_link(
869
871
  (ComponentShadow **)((char *)comp_shdw + offset),
870
872
  new_value, shadow);
@@ -884,13 +886,13 @@ class World
884
886
  else {
885
887
  int i;
886
888
  VALUE comp = comp_shdw->self;
887
- VALUE *ptr = RARRAY(connects)->ptr;
888
- long len = RARRAY(connects)->len;
889
+ VALUE *ptr = RARRAY_PTR(connects);
890
+ long len = RARRAY_LEN(connects);
889
891
 
890
892
  for (i = 0; i < len; i++) {
891
893
  VALUE pair = ptr[i];
892
- VALUE input_var = RARRAY(pair)->ptr[0];
893
- VALUE connect_spec = RARRAY(pair)->ptr[1];
894
+ VALUE input_var = RARRAY_PTR(pair)[0];
895
+ VALUE connect_spec = RARRAY_PTR(pair)[1];
894
896
  VALUE input_port;
895
897
  VALUE other_port;
896
898
 
@@ -925,11 +927,11 @@ class World
925
927
  if (!RTEST(resets))
926
928
  return 0;
927
929
 
928
- cont_resets = RARRAY(resets)->ptr[0];
930
+ cont_resets = RARRAY_PTR(resets)[0];
929
931
  var = (ContVar *)&FIRST_CONT_VAR(comp_shdw);
930
932
  did_reset = 0;
931
933
 
932
- len = RARRAY(cont_resets)->len;
934
+ len = RARRAY_LEN(cont_resets);
933
935
  for (i = len; i > 0; i--, var++) {
934
936
  if (var->reset) {
935
937
  var->reset = 0;
@@ -948,8 +950,8 @@ class World
948
950
 
949
951
  assert(RTEST(actions));
950
952
 
951
- for (i = 0; i < RARRAY(actions)->len; i++) {
952
- VALUE val = RARRAY(actions)->ptr[i];
953
+ for (i = 0; i < RARRAY_LEN(actions); i++) {
954
+ VALUE val = RARRAY_PTR(actions)[i];
953
955
  //%% hook_call_action(comp, val);
954
956
 
955
957
  if (SYMBOL_P(val))
@@ -959,8 +961,8 @@ class World
959
961
  //## this tech. could be applied in EVENT and RESET.
960
962
  //## also, component-gen can make use of this optimization
961
963
  //## for procs, using code similar to that for guards.
962
- //# rb_obj_instance_eval(1, &RARRAY(actions)->ptr[i], comp);
963
- //# rb_iterate(my_instance_eval, comp, call_block, RARRAY(actions)->ptr[i]);
964
+ //# rb_obj_instance_eval(1, &RARRAY_PTR(actions)[i], comp);
965
+ //# rb_iterate(my_instance_eval, comp, call_block, RARRAY_PTR(actions)[i]);
964
966
  }
965
967
  }
966
968
 
@@ -1034,7 +1036,7 @@ class World
1034
1036
  {
1035
1037
  VALUE comp;
1036
1038
  ComponentShadow *comp_shdw;
1037
- struct RArray *list;
1039
+ RS_DVector *list;
1038
1040
  int list_i;
1039
1041
  VALUE *ptr;
1040
1042
  long len, cur;
@@ -1045,7 +1047,7 @@ class World
1045
1047
  if (shadow->discrete_step == 0)
1046
1048
  comp_shdw->checked = 0;
1047
1049
 
1048
- len = RARRAY(comp_shdw->outgoing)->len - 1; //# last is flags
1050
+ len = RARRAY_LEN(comp_shdw->outgoing) - 1; //# last is flags
1049
1051
  cur = len;
1050
1052
 
1051
1053
  if (len == 0) {
@@ -1053,7 +1055,7 @@ class World
1053
1055
  continue;
1054
1056
  }
1055
1057
 
1056
- ptr = RARRAY(comp_shdw->outgoing)->ptr;
1058
+ ptr = RARRAY_PTR(comp_shdw->outgoing);
1057
1059
  if (sync_retry)
1058
1060
  cur -= 4 * comp_shdw->tmp.trans.idx;
1059
1061
  else
@@ -1102,14 +1104,14 @@ class World
1102
1104
  comp_shdw->checked = 1;
1103
1105
  }
1104
1106
  }
1105
- assert(RARRAY(shadow->prev_awake)->len == 0);
1107
+ assert(rs_dv(shadow->prev_awake)->len == 0);
1106
1108
  }
1107
1109
 
1108
1110
  inline static void do_sync_phase(#{World.shadow_struct_name} *shadow)
1109
1111
  {
1110
1112
  VALUE comp;
1111
1113
  ComponentShadow *comp_shdw;
1112
- struct RArray *list;
1114
+ RS_DVector *list;
1113
1115
  int list_i;
1114
1116
  int changed;
1115
1117
 
@@ -1126,7 +1128,7 @@ class World
1126
1128
  }
1127
1129
  }
1128
1130
 
1129
- assert(RARRAY(shadow->curr_S)->len == 0);
1131
+ assert(rs_dv(shadow->curr_S)->len == 0);
1130
1132
  SWAP_VALUE(shadow->curr_S, shadow->next_S);
1131
1133
  //%% hook_sync_step(shadow->curr_S, INT2BOOL(changed));
1132
1134
  } while (changed);
@@ -1163,7 +1165,7 @@ class World
1163
1165
 
1164
1166
  SWAP_VALUE(shadow->prev_awake, shadow->awake);
1165
1167
 
1166
- while (RARRAY(shadow->prev_awake)->len) {
1168
+ while (rs_dv(shadow->prev_awake)->len) {
1167
1169
  //%% hook_enter_guard_phase();
1168
1170
  check_guards(shadow, sync_retry);
1169
1171
  //%% hook_leave_guard_phase();
@@ -1174,7 +1176,7 @@ class World
1174
1176
  sync_retry = 1;
1175
1177
  }
1176
1178
 
1177
- if (!RARRAY(shadow->curr_T)->len) {
1179
+ if (!rs_dv(shadow->curr_T)->len) {
1178
1180
  //%% hook_end_step();
1179
1181
  break; //# out of main loop
1180
1182
  }
@@ -1182,7 +1184,7 @@ class World
1182
1184
  EACH_COMP_DO(shadow->curr_T) {
1183
1185
  //%% hook_begin_eval_events(comp);
1184
1186
  if (eval_events(comp_shdw, shadow))
1185
- rb_ary_push(shadow->active_E, comp);
1187
+ rs_dv_push(rs_dv(shadow->active_E), comp);
1186
1188
  //%% hook_end_eval_events(comp);
1187
1189
  }
1188
1190
 
@@ -1192,22 +1194,22 @@ class World
1192
1194
  //%% hook_export_events(comp, comp_shdw->event_values);
1193
1195
  }
1194
1196
  SWAP_VALUE(shadow->active_E, shadow->prev_active_E);
1195
- assert(RARRAY(shadow->active_E)->len == 0);
1197
+ assert(rs_dv(shadow->active_E)->len == 0);
1196
1198
 
1197
1199
  //%% hook_enter_eval_phase();
1198
1200
  EACH_COMP_DO(shadow->curr_T) {
1199
1201
  //%% hook_begin_eval_resets(comp);
1200
1202
  if (eval_continuous_resets(comp_shdw, shadow))
1201
- rb_ary_push(shadow->curr_CR, comp);
1203
+ rs_dv_push(rs_dv(shadow->curr_CR), comp);
1202
1204
  eval_constant_resets(comp_shdw, shadow);
1203
1205
  eval_port_connects(comp_shdw, shadow);
1204
1206
  //%% hook_end_eval_resets(comp);
1205
1207
 
1206
1208
  if (RTEST(cur_actions(comp_shdw)))
1207
- rb_ary_push(shadow->curr_A, comp);
1209
+ rs_dv_push(rs_dv(shadow->curr_A), comp);
1208
1210
 
1209
1211
  if (RTEST(cur_posts(comp_shdw)))
1210
- rb_ary_push(shadow->curr_P, comp);
1212
+ rs_dv_push(rs_dv(shadow->curr_P), comp);
1211
1213
  }
1212
1214
  //%% hook_leave_eval_phase();
1213
1215
 
@@ -1215,7 +1217,7 @@ class World
1215
1217
  EACH_COMP_DO(shadow->curr_A) {
1216
1218
  do_actions(comp_shdw, cur_actions(comp_shdw), shadow);
1217
1219
  }
1218
- RARRAY(shadow->curr_A)->len = 0;
1220
+ rs_dv(shadow->curr_A)->len = 0;
1219
1221
  //%% hook_leave_action_phase();
1220
1222
 
1221
1223
  //%% hook_begin_parallel_assign();
@@ -1223,7 +1225,7 @@ class World
1223
1225
  EACH_COMP_DO(shadow->curr_CR) {
1224
1226
  did_reset = assign_new_cont_values(comp_shdw) || did_reset;
1225
1227
  }
1226
- RARRAY(shadow->curr_CR)->len = 0;
1228
+ rs_dv(shadow->curr_CR)->len = 0;
1227
1229
  did_reset = assign_new_constant_values(shadow) || did_reset;
1228
1230
  did_reset = assign_new_links(shadow) || did_reset;
1229
1231
  did_reset = assign_new_ports(shadow) || did_reset;
@@ -1233,7 +1235,7 @@ class World
1233
1235
  EACH_COMP_DO(shadow->curr_P) {
1234
1236
  do_actions(comp_shdw, cur_posts(comp_shdw), shadow);
1235
1237
  }
1236
- RARRAY(shadow->curr_P)->len = 0;
1238
+ rs_dv(shadow->curr_P)->len = 0;
1237
1239
  //%% hook_leave_post_phase();
1238
1240
 
1239
1241
  EACH_COMP_DO(shadow->curr_T) {
@@ -1264,15 +1266,15 @@ class World
1264
1266
  else
1265
1267
  move_comp(comp, shadow->curr_T, shadow->awake);
1266
1268
  }
1267
- assert(RARRAY(shadow->curr_T)->len == 0);
1268
- assert(RARRAY(shadow->prev_awake)->len == 0);
1269
+ assert(rs_dv(shadow->curr_T)->len == 0);
1270
+ assert(rs_dv(shadow->prev_awake)->len == 0);
1269
1271
 
1270
1272
  //# Clear event values.
1271
1273
  EACH_COMP_DO(shadow->prev_active_E) {
1272
- rb_mem_clear(RARRAY(comp_shdw->event_values)->ptr,
1273
- RARRAY(comp_shdw->event_values)->len);
1274
+ rb_mem_clear(RARRAY_PTR(comp_shdw->event_values),
1275
+ RARRAY_LEN(comp_shdw->event_values));
1274
1276
  }
1275
- RARRAY(shadow->prev_active_E)->len = 0;
1277
+ rs_dv(shadow->prev_active_E)->len = 0;
1276
1278
 
1277
1279
  //%% hook_end_step();
1278
1280
  }
@@ -1302,9 +1304,10 @@ class World
1302
1304
 
1303
1305
  cl.class_eval do
1304
1306
  shadow_library_source_file.include(Component.shadow_library_include_file)
1307
+ shadow_library_source_file.include("dvector/dvector.h")
1305
1308
 
1306
1309
  if (instance_methods(false) + protected_instance_methods(false) +
1307
- private_instance_methods(false)).include?("step_discrete")
1310
+ private_instance_methods(false)).grep(/^step_discrete$/).size > 0
1308
1311
  warn "Redefining step_discrete in #{self}"
1309
1312
  end
1310
1313
 
@@ -1315,7 +1318,7 @@ class World
1315
1318
  # at this point, we know the file is complete
1316
1319
  file_str = meth.parent.to_s
1317
1320
 
1318
- known_hooks ||= file_str.scan(hook)
1321
+ known_hooks ||= file_str.scan(hook).map {|s|s.to_sym}
1319
1322
  unknown_hooks = cl_hooks - known_hooks
1320
1323
 
1321
1324
  unless unknown_hooks.empty?