Skip to content

Instantly share code, notes, and snippets.

@methodmissing
Created February 6, 2010 00:13
Show Gist options
  • Save methodmissing/296419 to your computer and use it in GitHub Desktop.
Save methodmissing/296419 to your computer and use it in GitHub Desktop.
Benchmark File Input Size RBS-ruby-100205.001747 RBS-ruby-100205.020911 RBS-ruby-100205.224359
macro-benchmarks/bm_dirp.rb 10000 0.68319 0.652077 0.685246
macro-benchmarks/bm_list.rb 1000 0.055925 0.056056 0.056541
macro-benchmarks/bm_list.rb 10000 4.752666 4.764763 4.917335
macro-benchmarks/bm_mpart.rb 300 0.099293 0.094168 0.091411
macro-benchmarks/bm_norvig_spelling.rb 50 9.678383 9.480905 9.71165
macro-benchmarks/bm_parse_log.rb 100 1.369653 0.26482 1.360127
macro-benchmarks/bm_pi.rb 1000 0.027939 0.028057 0.028157
macro-benchmarks/bm_pi.rb 10000 2.178629 2.189743 2.197385
macro-benchmarks/bm_rcs.rb 100 0.933577 0.943785 0.932224
macro-benchmarks/bm_sudoku.rb 1 8.212145 8.15188 8.224961
micro-benchmarks/bm_app_factorial.rb 5000 0.033342 0.032946 0.033446
micro-benchmarks/bm_app_fib.rb 30 1.245739 1.343998 1.24713
micro-benchmarks/bm_app_fib.rb 35 13.527407 14.853681 13.579695
micro-benchmarks/bm_app_tak.rb 7 0.856187 0.930009 0.858613
micro-benchmarks/bm_app_tak.rb 8 2.50221 2.668221 2.505396
micro-benchmarks/bm_app_tak.rb 9 6.630396 7.088128 6.634796
micro-benchmarks/bm_app_tarai.rb 3 2.944038 3.15839 2.949502
micro-benchmarks/bm_app_tarai.rb 4 3.55354 3.807121 3.554575
micro-benchmarks/bm_app_tarai.rb 5 4.300135 4.621853 4.302312
micro-benchmarks/bm_binary_trees.rb 1 49.748987 51.753205 49.869174
micro-benchmarks/bm_count_multithreaded.rb 1 0.006091 0.006343 0.006132
micro-benchmarks/bm_count_multithreaded.rb 2 0.012157 0.012159 0.0121
micro-benchmarks/bm_count_multithreaded.rb 4 0.024377 0.024303 0.024338
micro-benchmarks/bm_count_multithreaded.rb 8 0.049235 0.049368 0.048809
micro-benchmarks/bm_count_multithreaded.rb 16 0.09925 0.0988340000000001 0.098136
micro-benchmarks/bm_count_shared_thread.rb 1 0.062857 0.063225 0.063199
micro-benchmarks/bm_count_shared_thread.rb 2 0.062913 0.063509 0.062934
micro-benchmarks/bm_count_shared_thread.rb 4 0.062911 0.0635570000000001 0.063053
micro-benchmarks/bm_count_shared_thread.rb 8 0.063426 0.064463 0.063503
micro-benchmarks/bm_count_shared_thread.rb 16 0.063395 0.064916 0.063694
micro-benchmarks/bm_eval.rb 1000000 2.211414 2.276136 2.224023
micro-benchmarks/bm_fannkuch.rb 6 0.006248 0.006441 0.006423
micro-benchmarks/bm_fannkuch.rb 8 0.476277 0.483722 0.477928
micro-benchmarks/bm_fannkuch.rb 10 53.259275 54.250005 53.395218
micro-benchmarks/bm_fasta.rb 1000000 26.163061 25.591561 26.529614
micro-benchmarks/bm_fractal.rb 5 5.136566 5.118948 5.141513
micro-benchmarks/bm_gc_array.rb 1 30.395812 36.075473 31.29858
micro-benchmarks/bm_gc_mb.rb 500000 0.592804 0.604621 0.598503
micro-benchmarks/bm_gc_mb.rb 1000000 1.683061 1.69975 1.698979
micro-benchmarks/bm_gc_mb.rb 3000000 9.34722 9.367718 9.427848
micro-benchmarks/bm_gc_string.rb 1 5.816545 5.596305 5.831095
micro-benchmarks/bm_knucleotide.rb 1 1.329573 1.332282 1.336542
micro-benchmarks/bm_lucas_lehmer.rb 9689 3.607395 4.724456 4.719543
micro-benchmarks/bm_lucas_lehmer.rb 9941 5.079744 5.08689 5.085711
micro-benchmarks/bm_lucas_lehmer.rb 11213 7.240807 7.25021 7.248728
micro-benchmarks/bm_lucas_lehmer.rb 19937 39.003981 39.023985 39.026424
micro-benchmarks/bm_mbari_bogus1.rb 1 0.022264 0.022122 0.02245
micro-benchmarks/bm_mbari_bogus2.rb 1 0.007945 0.007128 0.00798
micro-benchmarks/bm_mergesort.rb 1 2.078423 2.06076 2.122289
micro-benchmarks/bm_mergesort_hongli.rb 3000 4.082899 4.117249 4.138487
micro-benchmarks/bm_meteor_contest.rb 1 27.887345 27.876489 28.310189
micro-benchmarks/bm_monte_carlo_pi.rb 10000000 13.305697 12.9328 13.418434
micro-benchmarks/bm_nbody.rb 100000 8.48873 8.649776 8.488598
micro-benchmarks/bm_nsieve.rb 9 15.816568 15.842241 15.795529
micro-benchmarks/bm_nsieve_bits.rb 8 17.510208 17.03378 17.541104
micro-benchmarks/bm_open_many_files.rb 50000 0.475781 0.483917 0.475442
micro-benchmarks/bm_partial_sums.rb 2500000 20.362203 21.216608 20.934496
micro-benchmarks/bm_quicksort.rb 1 3.79364 3.835882 3.839536
micro-benchmarks/bm_read_large.rb 100 5.729971 5.710267 5.741339
micro-benchmarks/bm_regex_dna.rb 20 3.351038 3.001645 3.341691
micro-benchmarks/bm_reverse_compliment.rb 1 3.669281 3.808386 3.647799
micro-benchmarks/bm_so_ackermann.rb 7 0.405913 0.400172 0.405752
micro-benchmarks/bm_so_ackermann.rb 9 6.564542 6.458367 6.560555
micro-benchmarks/bm_so_array.rb 9000 4.863508 4.949789 4.859505
micro-benchmarks/bm_so_count_words.rb 100 2.882116 2.890802 2.870838
micro-benchmarks/bm_so_exception.rb 500000 10.253348 10.36271 10.27429
micro-benchmarks/bm_so_lists.rb 1000 7.694572 7.808459 7.675046
micro-benchmarks/bm_so_lists_small.rb 1000 1.543141 1.560071 1.541006
micro-benchmarks/bm_so_matrix.rb 60 1.533322 1.574854 1.533368
micro-benchmarks/bm_so_object.rb 500000 1.681234 1.694682 1.677264
micro-benchmarks/bm_so_object.rb 1000000 3.354599 3.390256 3.345543
micro-benchmarks/bm_so_object.rb 1500000 5.050106 5.098473 5.036319
micro-benchmarks/bm_so_sieve.rb 4000 53.224554 53.598101 53.186547
micro-benchmarks/bm_spectral_norm.rb 100 0.775197 0.792581 0.773314
micro-benchmarks/bm_string_concat.rb 10000000 5.753127 3.427915 5.76585
micro-benchmarks/bm_sum_file.rb 100 9.205506 9.144994 9.207701
micro-benchmarks/bm_word_anagrams.rb 1 8.010739 7.848207 8.045152
micro-benchmarks/bm_write_large.rb 100 0.979049 0.953965 0.944034
diff --git a/array.c b/array.c
index 89f74d0..2053e0b 100644
--- a/array.c
+++ b/array.c
@@ -200,7 +200,10 @@ static VALUE
ary_make_shared(ary)
VALUE ary;
{
- if (!FL_TEST(ary, ELTS_SHARED)) {
+#ifndef OPT_ARRAY
+ if (FL_TEST(ary, ELTS_SHARED))
+ return RARRAY(ary)->aux.shared;
+#endif
NEWOBJ(shared, struct RArray);
OBJSETUP(shared, rb_cArray, T_ARRAY);
@@ -211,12 +214,14 @@ ary_make_shared(ary)
FL_SET(ary, ELTS_SHARED);
OBJ_FREEZE(shared);
return (VALUE)shared;
- }
- else {
- return RARRAY(ary)->aux.shared;
- }
}
+#ifdef OPT_ARRAY
+#define ary_make_shared(ary) \
+ ({ VALUE _ary = (ary); \
+ FL_TEST(_ary, ELTS_SHARED) ? RARRAY(_ary)->aux.shared : ary_make_shared(_ary); })
+#endif
+
VALUE
rb_assoc_new(car, cdr)
VALUE car, cdr;
@@ -710,8 +715,10 @@ rb_ary_subseq(ary, beg, len)
VALUE klass, ary2, shared;
VALUE *ptr;
+#ifndef OPT_ARRAY
if (beg > RARRAY(ary)->len) return Qnil;
if (beg < 0 || len < 0) return Qnil;
+#endif
if (RARRAY(ary)->len < len || RARRAY(ary)->len < beg + len) {
len = RARRAY(ary)->len - beg;
@@ -732,6 +739,13 @@ rb_ary_subseq(ary, beg, len)
return ary2;
}
+#ifdef OPT_ARRAY
+#define rb_ary_subseq(a, b, l) \
+ ({ VALUE _a = (a); \
+ long _b = (b), _l = (l); \
+ (_b > RARRAY(_a)->len) || (_b < 0 || _l < 0) ? Qnil : rb_ary_subseq(_a, _b, _l); })
+#endif
+
/*
* call-seq:
* array[index] -> obj or nil
@@ -1052,12 +1066,18 @@ rb_ary_indexes(argc, argv, ary)
}
VALUE
+#ifdef rb_ary_to_ary
+orig_rb_ary_to_ary(obj)
+#else
rb_ary_to_ary(obj)
+#endif
VALUE obj;
{
+#ifndef OPT_ARRAY
if (TYPE(obj) == T_ARRAY) {
return obj;
}
+#endif
if (rb_respond_to(obj, rb_intern("to_ary"))) {
return rb_convert_type(obj, T_ARRAY, "Array", "to_ary");
}
@@ -1380,14 +1400,20 @@ inspect_join(ary, arg)
}
VALUE
+#ifdef rb_ary_join
+orig_rb_ary_join(ary, sep)
+#else
rb_ary_join(ary, sep)
+#endif
VALUE ary, sep;
{
long len = 1, i;
int taint = Qfalse;
VALUE result, tmp;
+#ifndef OPT_ARRAY
if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
+#endif
if (OBJ_TAINTED(ary) || OBJ_TAINTED(sep)) taint = Qtrue;
for (i=0; i<RARRAY(ary)->len; i++) {
@@ -1465,11 +1491,16 @@ rb_ary_join_m(argc, argv, ary)
*/
VALUE
+#ifdef rb_ary_to_s
+orig_rb_ary_to_s(ary)
+#else
rb_ary_to_s(ary)
+#endif
VALUE ary;
{
+#ifndef OPT_ARRAY
if (RARRAY(ary)->len == 0) return rb_str_new(0, 0);
-
+#endif
return rb_ary_join(ary, rb_output_fs);
}
@@ -2009,14 +2040,20 @@ rb_ary_delete(ary, item)
}
VALUE
+#ifdef rb_ary_delete_at
+orig_rb_ary_delete_at(ary, pos)
+#else
rb_ary_delete_at(ary, pos)
+#endif
VALUE ary;
long pos;
{
long i, len = RARRAY(ary)->len;
VALUE del;
+#ifndef OPT_ARRAY
if (pos >= len) return Qnil;
+#endif
if (pos < 0) {
pos += len;
if (pos < 0) return Qnil;
@@ -2623,7 +2660,9 @@ recursive_equal(ary1, ary2, recur)
{
long i;
+#ifndef OPT_ARRAY
if (recur) return Qfalse;
+#endif
for (i=0; i<RARRAY(ary1)->len; i++) {
if (!rb_equal(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
return Qfalse;
@@ -2631,6 +2670,13 @@ recursive_equal(ary1, ary2, recur)
return Qtrue;
}
+#ifdef OPT_ARRAY
+#define recursive_equal(ary1, ary2, recur) \
+ ({ VALUE _ary1 = (ary1), _ary2 = (ary2); \
+ int _recur = (recur); \
+ _recur ? Qfalse : recursive_equal(_ary1, _ary2, _recur); })
+#endif
+
/*
* call-seq:
* array == other_array -> bool
@@ -2668,7 +2714,9 @@ recursive_eql(ary1, ary2, recur)
{
long i;
+#ifndef OPT_ARRAY
if (recur) return Qfalse;
+#endif
for (i=0; i<RARRAY(ary1)->len; i++) {
if (!rb_eql(rb_ary_elt(ary1, i), rb_ary_elt(ary2, i)))
return Qfalse;
@@ -2676,6 +2724,13 @@ recursive_eql(ary1, ary2, recur)
return Qtrue;
}
+#ifdef OPT_ARRAY
+#define recursive_eql(ary1, ary2, recur) \
+ ({ VALUE _ary1 = (ary1), _ary2 = (ary2); \
+ int _recur = (recur); \
+ _recur ? Qfalse : recursive_eql(_ary1, _ary2, _recur); })
+#endif
+
/*
* call-seq:
* array.eql?(other) -> true or false
@@ -2770,7 +2825,9 @@ recursive_cmp(ary1, ary2, recur)
{
long i, len;
+#ifndef OPT_ARRAY
if (recur) return Qnil;
+#endif
len = RARRAY(ary1)->len;
if (len > RARRAY(ary2)->len) {
len = RARRAY(ary2)->len;
@@ -2784,6 +2841,13 @@ recursive_cmp(ary1, ary2, recur)
return Qundef;
}
+#ifdef OPT_ARRAY
+#define recursive_cmp(ary1, ary2, recur) \
+ ({ VALUE _ary1 = (ary1), _ary2 = (ary2); \
+ int _recur = (recur); \
+ _recur ? Qnil : recursive_cmp(_ary1, _ary2, _recur); })
+#endif
+
/*
* call-seq:
* array <=> other_array -> -1, 0, +1
@@ -3771,7 +3835,11 @@ Init_Array()
rb_define_method(rb_cArray, "initialize", rb_ary_initialize, -1);
rb_define_method(rb_cArray, "initialize_copy", rb_ary_replace, 1);
+#ifdef OPT_ARRAY
+ rb_define_method(rb_cArray, "to_s", orig_rb_ary_to_s, 0);
+#else
rb_define_method(rb_cArray, "to_s", rb_ary_to_s, 0);
+#endif
rb_define_method(rb_cArray, "inspect", rb_ary_inspect, 0);
rb_define_method(rb_cArray, "to_a", rb_ary_to_a, 0);
rb_define_method(rb_cArray, "to_ary", rb_ary_to_ary_m, 0);
diff --git a/bignum.c b/bignum.c
index 8e27369..e6aa02c 100644
--- a/bignum.c
+++ b/bignum.c
@@ -90,7 +90,9 @@ get2comp(x)
BDIGIT *ds = BDIGITS(x);
BDIGIT_DBL num;
+#ifndef OPT_BIGNUM
if (!i) return;
+#endif
while (i--) ds[i] = ~ds[i];
i = 0; num = 1;
do {
@@ -105,6 +107,12 @@ get2comp(x)
}
}
+#ifdef OPT_BIGNUM
+#define get2comp(x) \
+ ({ VALUE _x = (x); \
+ if (RBIGNUM(_x)->len) get2comp(_x); })
+#endif
+
void
rb_big_2comp(x) /* get 2's complement */
VALUE x;
@@ -118,13 +126,20 @@ bigtrunc(x)
{
long len = RBIGNUM(x)->len;
BDIGIT *ds = BDIGITS(x);
-
+#ifndef OPT_BIGNUM
if (len == 0) return x;
+#endif
while (--len && !ds[len]);
RBIGNUM(x)->len = ++len;
return x;
}
+#ifdef OPT_BIGNUM
+#define bigtrunc(x) \
+ ({ VALUE _x = (x); \
+ RBIGNUM(_x)->len == 0 ? _x : bigtrunc(_x); })
+#endif
+
static VALUE
bigfixize(x)
VALUE x;
@@ -206,6 +221,7 @@ rb_int2big(n)
return big;
}
+#ifndef OPT_BIGNUM
VALUE
rb_uint2inum(n)
unsigned long n;
@@ -221,6 +237,7 @@ rb_int2inum(n)
if (FIXABLE(n)) return LONG2FIX(n);
return rb_int2big(n);
}
+#endif
#ifdef HAVE_LONG_LONG
@@ -624,6 +641,7 @@ rb_ll2big(n)
return big;
}
+#ifndef OPT_BIGNUM
VALUE
rb_ull2inum(n)
unsigned LONG_LONG n;
@@ -639,7 +657,7 @@ rb_ll2inum(n)
if (FIXABLE(n)) return LONG2FIX(n);
return rb_ll2big(n);
}
-
+#endif
#endif /* HAVE_LONG_LONG */
VALUE
@@ -671,9 +689,11 @@ rb_big2str0(x, base, trim)
VALUE ss;
char *s;
+#ifndef OPT_BIGNUM
if (FIXNUM_P(x)) {
return rb_fix2str(x, base);
}
+#endif
i = RBIGNUM(x)->len;
if (BIGZEROP(x)) {
return rb_str_new2("0");
@@ -756,6 +776,13 @@ rb_big2str0(x, base, trim)
return ss;
}
+#ifdef OPT_BIGNUM
+#define rb_big2str0(x, base, trim) \
+ ({ VALUE _x = (x); \
+ int _base = (base), _trim = (trim); \
+ FIXNUM_P(_x) ? rb_fix2str(_x, _base) : rb_big2str0(_x, _base, _trim); })
+#endif
+
VALUE
rb_big2str(VALUE x, int base)
{
@@ -1589,7 +1616,9 @@ bdigbitsize(BDIGIT x)
int nb = BITSPERDIG / 2;
BDIGIT bits = (~0 << nb);
+#ifndef OPT_BIGNUM
if (!x) return 0;
+#endif
while (x > 1) {
if (x & bits) {
size += nb;
@@ -1603,6 +1632,12 @@ bdigbitsize(BDIGIT x)
return size;
}
+#ifdef OPT_BIGNUM
+#define bdigbitsize(x) \
+ ({ BDIGIT _x = (x); \
+ !_x ? 0 : bdigbitsize(_x); })
+#endif
+
static VALUE big_lshift _((VALUE, unsigned long));
static VALUE big_rshift _((VALUE, unsigned long));
@@ -1773,13 +1808,19 @@ bigsqr(x)
*/
VALUE
+#ifdef OPT_BIGNUM
+orig_rb_big_pow(x, y)
+#else
rb_big_pow(x, y)
+#endif
VALUE x, y;
{
double d;
long yy;
+#ifndef OPT_BIGNUM
if (y == INT2FIX(0)) return INT2FIX(1);
+#endif
switch (TYPE(y)) {
case T_FLOAT:
d = RFLOAT(y)->value;
@@ -1996,13 +2037,21 @@ rb_big_xor(xx, yy)
static VALUE
check_shiftdown(VALUE y, VALUE x)
{
+#ifndef OPT_BIGNUM
if (!RBIGNUM(x)->len) return INT2FIX(0);
+#endif
if (RBIGNUM(y)->len > SIZEOF_LONG / SIZEOF_BDIGITS) {
return RBIGNUM(x)->sign ? INT2FIX(0) : INT2FIX(-1);
}
return Qnil;
}
+#ifdef OPT_BIGNUM
+#define check_shiftdown(y,x) \
+ ({ VALUE _y = (y), _x = (x); \
+ !(RBIGNUM(_x)->len) ? INT2FIX(0) : check_shiftdown(_y,_x); })
+#endif
+
/*
* call-seq:
* big << numeric => integer
@@ -2357,7 +2406,11 @@ Init_Bignum()
rb_define_method(rb_cBignum, "remainder", rb_big_remainder, 1);
rb_define_method(rb_cBignum, "quo", rb_big_quo, 1);
rb_define_method(rb_cBignum, "fdiv", rb_big_quo, 1);
+#ifdef OPT_BIGNUM
+ rb_define_method(rb_cBignum, "**", orig_rb_big_pow, 1);
+#else
rb_define_method(rb_cBignum, "**", rb_big_pow, 1);
+#endif
rb_define_method(rb_cBignum, "&", rb_big_and, 1);
rb_define_method(rb_cBignum, "|", rb_big_or, 1);
rb_define_method(rb_cBignum, "^", rb_big_xor, 1);
diff --git a/class.c b/class.c
index 054be60..27b49f6 100644
--- a/class.c
+++ b/class.c
@@ -645,7 +645,6 @@ class_instance_method_list(argc, argv, mod, func)
rb_scan_args(argc, argv, "01", &r);
recur = RTEST(r);
}
-
list = st_init_numtable();
for (; mod; mod = RCLASS(mod)->super) {
st_foreach(RCLASS(mod)->m_tbl, method_entry, (st_data_t)list);
@@ -656,7 +655,6 @@ class_instance_method_list(argc, argv, mod, func)
ary = rb_ary_new();
st_foreach(list, func, ary);
st_free_table(list);
-
return ary;
}
diff --git a/distro/installer.rb b/distro/installer.rb
index 9b7411e..3f14c1f 100755
--- a/distro/installer.rb
+++ b/distro/installer.rb
@@ -269,7 +269,7 @@ private
prelibs << " -lsystem_allocator"
end
File.open("make.sh", "w") do |f|
- f.write("#!/bin/bash")
+ f.write("#!/bin/bash\n")
f.write("exec make PRELIBS='#{prelibs}' \"$@\"")
f.chmod(0755)
end
diff --git a/eval.c b/eval.c
index 4ec77d9..2d8f1f8 100644
--- a/eval.c
+++ b/eval.c
@@ -369,14 +369,24 @@ struct cache_entry { /* method hash table. */
};
static struct cache_entry cache[CACHE_SIZE];
+#ifdef OPT_EVAL
+int ruby_running = 0;
+#else
static int ruby_running = 0;
+#endif
void
+#ifdef rb_clear_cache
+orig_rb_clear_cache()
+#else
rb_clear_cache()
+#endif
{
struct cache_entry *ent, *end;
+#ifndef OPT_EVAL
if (!ruby_running) return;
+#endif
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
ent->mid = 0;
@@ -391,7 +401,9 @@ rb_clear_cache_for_undef(klass, id)
{
struct cache_entry *ent, *end;
+#ifndef OPT_EVAL
if (!ruby_running) return;
+#endif
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
if (ent->mid == id &&
@@ -403,13 +415,22 @@ rb_clear_cache_for_undef(klass, id)
}
}
+#ifdef OPT_EVAL
+#define rb_clear_cache_for_undef(klass, id) \
+ ({ VALUE _klass = (klass); \
+ ID _id = (id); \
+ if (ruby_running) rb_clear_cache_for_undef(_klass, _id); })
+#endif
+
static void
rb_clear_cache_by_id(id)
ID id;
{
struct cache_entry *ent, *end;
+#ifndef OPT_EVAL
if (!ruby_running) return;
+#endif
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
if (ent->mid == id) {
@@ -419,13 +440,25 @@ rb_clear_cache_by_id(id)
}
}
+#ifdef OPT_EVAL
+#define rb_clear_cache_by_id(id) \
+ ({ ID _id = (id); \
+ if (ruby_running) rb_clear_cache_by_id(_id); })
+#endif
+
void
+#ifdef rb_clear_cache_by_class
+orig_rb_clear_cache_by_class(klass)
+#else
rb_clear_cache_by_class(klass)
+#endif
VALUE klass;
{
struct cache_entry *ent, *end;
+#ifndef OPT_EVAL
if (!ruby_running) return;
+#endif
ent = cache; end = ent + CACHE_SIZE;
while (ent < end) {
if (ent->klass == klass || ent->origin == klass) {
@@ -507,7 +540,9 @@ search_method(klass, id, origin)
{
st_data_t body;
+#ifndef OPT_EVAL
if (!klass) return 0;
+#endif
while (!st_lookup(RCLASS(klass)->m_tbl, id, &body)) {
klass = RCLASS(klass)->super;
if (!klass) return 0;
@@ -517,6 +552,14 @@ search_method(klass, id, origin)
return (NODE *)body;
}
+#ifdef OPT_EVAL
+#define search_method(klass, id, origin) \
+ ({ VALUE _klass = (klass); \
+ VALUE * _origin = (origin); \
+ ID _id = (id); \
+ !klass ? 0 : search_method(_klass, _id, _origin); })
+#endif
+
static NODE*
rb_get_method_body(klassp, idp, noexp)
VALUE *klassp;
@@ -1258,12 +1301,20 @@ static VALUE
get_backtrace(info)
VALUE info;
{
+#ifndef OPT_EVAL
if (NIL_P(info)) return Qnil;
+#endif
info = rb_funcall(info, rb_intern("backtrace"), 0);
if (NIL_P(info)) return Qnil;
return rb_check_backtrace(info);
}
+#ifdef OPT_EVAL
+#define get_backtrace(info) \
+ ({ VALUE _info = (info); \
+ NIL_P(_info) ? Qnil : get_backtrace(_info); })
+#endif
+
static void
set_backtrace(info, bt)
VALUE info, bt;
@@ -1279,8 +1330,9 @@ error_print()
const char * einfo;
long elen;
+#ifndef OPT_EVAL
if (NIL_P(ruby_errinfo)) return;
-
+#endif
PUSH_TAG(PROT_EMPTY);
errat = EXEC_TAG() ? Qnil : get_backtrace(ruby_errinfo);
if (EXEC_TAG()) goto error;
@@ -1375,6 +1427,11 @@ error_print()
POP_TAG();
}
+#ifdef OPT_EVAL
+#define error_print() \
+ ({ if(!NIL_P(ruby_errinfo)) error_print(); })
+#endif
+
#if defined(__APPLE__)
#define environ (*_NSGetEnviron())
#elif !defined(_WIN32) && !defined(__MACOS__) || defined(_WIN32_WCE)
@@ -2383,7 +2440,9 @@ arg_defined(self, node, buf, type)
int argc;
int i;
+#ifndef OPT_EVAL
if (!node) return type; /* no args */
+#endif
if (nd_type(node) == NODE_ARRAY) {
argc=node->nd_alen;
if (argc > 0) {
@@ -2400,6 +2459,15 @@ arg_defined(self, node, buf, type)
return type;
}
+#ifdef OPT_EVAL
+#define arg_defined(self, node, buf, type) \
+ ({ VALUE _self = (self); \
+ NODE *_node = (node); \
+ char *_buf = (buf); \
+ char *_type = (type); \
+ !_node ? _type : arg_defined(_self, _node, _buf, _type); })
+#endif
+
static const char*
is_defined(self, node, buf)
VALUE self;
@@ -2761,9 +2829,11 @@ call_trace_func(event, node, self, id, klass)
const char *event_name;
volatile rb_thread_t th = curr_thread;
+#ifndef OPT_EVAL
if (!trace_func) return;
if (tracing) return;
if (ruby_in_compile) return;
+#endif
if (id == ID_ALLOCATOR) return;
if (!(node_save = ruby_current_node)) {
@@ -2813,6 +2883,16 @@ call_trace_func(event, node, self, id, klass)
if (state) JUMP_TAG(state);
}
+#ifdef OPT_EVAL
+#define call_trace_func(event, node, self, id, klass) \
+ ({ rb_event_t _event = (event); \
+ NODE *_node = (node); \
+ VALUE _self = (self); \
+ ID _id = (id); \
+ VALUE _klass = (klass); \
+ if (trace_func || !tracing || !ruby_in_compile) call_trace_func(_event, _node, _self, _id, _klass); })
+#endif
+
static VALUE
avalue_to_svalue(v)
VALUE v;
@@ -2845,7 +2925,9 @@ svalue_to_avalue(v)
{
VALUE tmp, top;
+#ifndef OPT_EVAL
if (v == Qundef) return rb_ary_new2(0);
+#endif
tmp = rb_check_array_type(v);
if (NIL_P(tmp)) {
return rb_ary_new3(1, v);
@@ -2859,6 +2941,11 @@ svalue_to_avalue(v)
}
return tmp;
}
+#ifdef OPT_EVAL
+#define svalue_to_avalue(v) \
+ ({ VALUE _v = (v); \
+ _v == Qundef ? rb_ary_new2(0) : svalue_to_avalue(_v); })
+#endif
static VALUE
svalue_to_mrhs(v, lhs)
@@ -2867,7 +2954,9 @@ svalue_to_mrhs(v, lhs)
{
VALUE tmp;
+#ifndef OPT_EVAL
if (v == Qundef) return rb_ary_new2(0);
+#endif
tmp = rb_check_array_type(v);
if (NIL_P(tmp)) {
return rb_ary_new3(1, v);
@@ -2879,19 +2968,34 @@ svalue_to_mrhs(v, lhs)
return tmp;
}
+#ifdef OPT_EVAL
+#define svalue_to_mrhs(v, lhs) \
+ ({ VALUE _v = (v); \
+ NODE * _lhs = (lhs); \
+ _v == Qundef ? rb_ary_new2(0) : svalue_to_mrhs(_v,_lhs); })
+#endif
+
static VALUE
avalue_splat(v)
VALUE v;
{
+#ifndef OPT_EVAL
if (RARRAY(v)->len == 0) {
return Qundef;
}
+#endif
if (RARRAY(v)->len == 1) {
return RARRAY(v)->ptr[0];
}
return v;
}
+#ifdef OPT_EVAL
+#define avalue_splat(v) \
+ ({ VALUE _v = (v); \
+ RARRAY(_v)->len == 0 ? Qundef : avalue_splat(_v); })
+#endif
+
#if 1
VALUE
rb_Array(val)
@@ -2924,10 +3028,18 @@ static VALUE
splat_value(v)
VALUE v;
{
+#ifndef OPT_EVAL
if (NIL_P(v)) return rb_ary_new3(1, Qnil);
+#endif
return rb_Array(v);
}
+#ifdef OPT_EVAL
+#define splat_value(v) \
+ ({ VALUE _v = (v); \
+ NIL_P(_v) ? rb_ary_new3(1, Qnil) : splat_value(_v); })
+#endif
+
static VALUE
class_prefix(self, cpath)
VALUE self;
@@ -6933,16 +7045,21 @@ static VALUE
yield_under(under, self, args)
VALUE under, self, args;
{
- if (args == Qundef) {
+#ifndef OPT_EVAL
+ if (args == Qundef)
return exec_under(yield_under_i, under, 0, self);
- }
- else {
+#endif
VALUE info[2] = { args, self };
return exec_under(yield_args_under_i, under, 0, (VALUE)info);
- }
}
+#ifdef OPT_EVAL
+#define yield_under(under, self, args) \
+ ({ VALUE _under = (under), _self = (self), _args = (args); \
+ _args == Qundef ? exec_under(yield_under_i, _under, 0, _self) : yield_under(_under, _self, _args); })
+#endif
+
static VALUE
specific_eval(argc, argv, klass, self)
int argc;
@@ -8572,8 +8689,10 @@ scope_dup(scope)
ID *tbl;
VALUE *vars;
+#ifndef OPT_EVAL
scope->flags |= SCOPE_DONT_RECYCLE;
if (scope->flags & SCOPE_MALLOC) return;
+#endif
if (scope->local_tbl) {
tbl = scope->local_tbl;
@@ -8585,6 +8704,13 @@ scope_dup(scope)
}
}
+#ifdef OPT_EVAL
+#define scope_dup(scope) \
+ ({ struct SCOPE * _scope = (scope); \
+ _scope->flags |= SCOPE_DONT_RECYCLE; \
+ (_scope->flags & SCOPE_MALLOC) ? NULL : scope_dup(_scope); })
+#endif
+
static void
blk_mark(data)
struct BLOCK *data;
@@ -10063,6 +10189,7 @@ method_proc(method)
return proc;
}
+#ifndef OPT_EVAL
static VALUE
rb_obj_is_method(m)
VALUE m;
@@ -10072,6 +10199,11 @@ rb_obj_is_method(m)
}
return Qfalse;
}
+#else
+#define rb_obj_is_method(m) \
+ ({ VALUE _m = (m); \
+ (TYPE(_m) == T_DATA && RDATA(_m)->dmark == (RUBY_DATA_FUNC)bm_mark) ? Qtrue : Qfalse; })
+#endif
/*
* call-seq:
@@ -10787,10 +10919,12 @@ rb_gc_mark_threads()
{
rb_thread_t th;
+#ifndef OPT_EVAL
/* static global mark */
rb_gc_mark((VALUE)ruby_cref);
if (!curr_thread) return;
+#endif
rb_gc_mark(main_thread->thread);
rb_gc_mark(curr_thread->thread);
FOREACH_THREAD_FROM(main_thread, th) {
@@ -10808,13 +10942,21 @@ rb_gc_mark_threads()
if (loading_tbl) st_foreach(loading_tbl, mark_loading_thread, 0);
}
+#ifdef OPT_EVAL
+#define rb_gc_mark_threads() \
+ ({ rb_gc_mark((VALUE)ruby_cref); \
+ if (curr_thread) rb_gc_mark_threads(); })
+#endif
+
void
rb_gc_abort_threads()
{
rb_thread_t th;
+#ifndef OPT_EVAL
if (!main_thread)
return;
+#endif
FOREACH_THREAD_FROM(main_thread, th) {
if (rb_gc_is_thread_marked(th->thread)) continue;
@@ -10825,6 +10967,11 @@ rb_gc_abort_threads()
} END_FOREACH_FROM(main_thread, th);
}
+#ifdef OPT_EVAL
+#define rb_gc_abort_threads() \
+ ({ if (main_thread) rb_gc_abort_threads(); })
+#endif
+
static inline void
stack_free(th)
rb_thread_t th;
@@ -11137,7 +11284,9 @@ static void
rb_thread_remove(th)
rb_thread_t th;
{
+#ifndef OPT_EVAL
if (th->status == THREAD_KILLED) return;
+#endif
rb_thread_ready(th);
rb_thread_die(th);
@@ -11152,6 +11301,12 @@ rb_thread_remove(th)
#endif
}
+#ifdef OPT_EVAL
+#define rb_thread_remove(th) \
+ ({ rb_thread_t _th = (th); \
+ if (_th->status != THREAD_KILLED) rb_thread_remove(_th); })
+#endif
+
static int
rb_thread_dead(th)
rb_thread_t th;
@@ -11584,12 +11739,18 @@ rb_thread_schedule()
}
void
+#ifdef rb_thread_wait_fd
+orig_rb_thread_wait_fd(fd)
+#else
rb_thread_wait_fd(fd)
+#endif
int fd;
{
+#ifndef OPT_EVAL
if (rb_thread_critical) return;
if (ruby_in_compile) return;
if (curr_thread == curr_thread->next) return;
+#endif
if (curr_thread->status == THREAD_TO_KILL) return;
curr_thread->status = THREAD_STOPPED;
@@ -11599,11 +11760,17 @@ rb_thread_wait_fd(fd)
}
int
+#ifdef rb_thread_fd_writable
+orig_rb_thread_fd_writable(fd)
+#else
rb_thread_fd_writable(fd)
+#endif
int fd;
{
+#ifndef OPT_EVAL
if (rb_thread_critical) return Qtrue;
if (curr_thread == curr_thread->next) return Qtrue;
+#endif
if (curr_thread->status == THREAD_TO_KILL) return Qtrue;
if (curr_thread->status == THREAD_KILLED) return Qtrue;
@@ -12557,7 +12724,11 @@ rb_thread_alloc(klass)
return th;
}
+#ifdef OPT_EVAL
+int thread_init;
+#else
static int thread_init;
+#endif
#if defined(POSIX_SIGNAL)
#define CATCH_VTALRM() posix_signal(SIGVTALRM, catch_timer)
@@ -12642,13 +12813,19 @@ thread_timer(dummy)
}
void
+#ifdef rb_thread_start_timer
+orig_rb_thread_start_timer()
+#else
rb_thread_start_timer()
+#endif
{
void *args[2];
static pthread_cond_t start = PTHREAD_COND_INITIALIZER;
+#ifndef OPT_EVAL
if (thread_init) return;
if (rb_thread_alone()) return;
+#endif
CATCH_VTALRM();
args[0] = &time_thread;
args[1] = &start;
@@ -12662,15 +12839,22 @@ rb_thread_start_timer()
}
void
+#ifdef rb_thread_stop_timer
+orig_rb_thread_stop_timer()
+#else
rb_thread_stop_timer()
+#endif
{
+#ifndef OPT_EVAL
if (!thread_init) return;
+#endif
safe_mutex_lock(&time_thread.lock);
pthread_cond_signal(&time_thread.cond);
thread_init = 0;
pthread_cleanup_pop(1);
pthread_join(time_thread.thread, NULL);
}
+
#elif defined(HAVE_SETITIMER)
static void
catch_timer(sig)
@@ -12686,12 +12870,18 @@ catch_timer(sig)
}
void
+#ifdef rb_thread_start_timer
+orig_rb_thread_start_timer()
+#else
rb_thread_start_timer()
+#endif
{
struct itimerval tval;
+#ifndef OPT_EVAL
if (thread_init) return;
if (rb_thread_alone()) return;
+#endif
CATCH_VTALRM();
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 10000;
@@ -12701,17 +12891,24 @@ rb_thread_start_timer()
}
void
+#ifdef rb_thread_stop_timer
+orig_rb_thread_stop_timer()
+#else
rb_thread_stop_timer()
+#endif
{
struct itimerval tval;
+#ifndef OPT_EVAL
if (!thread_init) return;
+#endif
tval.it_interval.tv_sec = 0;
tval.it_interval.tv_usec = 0;
tval.it_value = tval.it_interval;
setitimer(ITIMER_VIRTUAL, &tval, NULL);
thread_init = 0;
}
+
#else /* !(_THREAD_SAFE || HAVE_SETITIMER) */
int rb_thread_tick = THREAD_TICK;
#endif
@@ -13570,11 +13767,17 @@ rb_thread_inspect(thread)
}
void
+#ifdef rb_thread_atfork
+orig_rb_thread_atfork()
+#else
rb_thread_atfork()
+#endif
{
rb_thread_t th;
+#ifndef OPT_EVAL
if (rb_thread_alone()) return;
+#endif
FOREACH_THREAD(th) {
if (th != curr_thread) {
rb_thread_die(th);
@@ -13966,10 +14169,10 @@ recursive_check(hash, obj)
VALUE hash;
VALUE obj;
{
- if (NIL_P(hash) || TYPE(hash) != T_HASH) {
+#ifndef OPT_EVAL
+ if (NIL_P(hash) || TYPE(hash) != T_HASH)
return Qfalse;
- }
- else {
+#endif
VALUE list = rb_hash_aref(hash, ID2SYM(rb_frame_last_func()));
if (NIL_P(list) || TYPE(list) != T_HASH)
@@ -13977,9 +14180,14 @@ recursive_check(hash, obj)
if (NIL_P(rb_hash_lookup(list, obj)))
return Qfalse;
return Qtrue;
- }
}
+#ifdef OPT_EVAL
+#define recursive_check(hash, obj) \
+ ({ VALUE _hash = (hash), _obj = (obj); \
+ NIL_P(_hash) || TYPE(_hash) != T_HASH ? Qfalse : recursive_check(_hash, _obj); })
+#endif
+
static VALUE
recursive_push(hash, obj)
VALUE hash;
diff --git a/gc.c b/gc.c
index 8c1c6d6..d27af71 100644
--- a/gc.c
+++ b/gc.c
@@ -342,8 +342,11 @@ static GC_TIME_TYPE gc_time = 0;
static int gc_collections = 0;
static int during_gc;
static int need_call_final = 0;
+#ifdef OPT_GC
+st_table *finalizer_table = 0;
+#else
static st_table *finalizer_table = 0;
-
+#endif
/************************************************************
* Heap and copy-on-write debugging support functions
@@ -1323,12 +1326,19 @@ mark_entry(key, value)
}
void
+#ifdef rb_mark_tbl
+orig_rb_mark_tbl(tbl)
+#else
rb_mark_tbl(tbl)
+#endif
st_table *tbl;
{
+#ifndef OPT_GC
if (!tbl) return;
+#endif
st_foreach(tbl, mark_entry, 0);
}
+
#define mark_tbl(tbl) rb_mark_tbl(tbl)
static int
@@ -1350,21 +1360,35 @@ mark_key(key, value)
}
void
+#ifdef rb_mark_set
+orig_rb_mark_set(tbl)
+#else
rb_mark_set(tbl)
+#endif
st_table *tbl;
{
+#ifndef OPT_GC
if (!tbl) return;
+#endif
st_foreach(tbl, mark_key, 0);
}
+
#define mark_set(tbl) rb_mark_set(tbl)
void
+#ifdef rb_mark_hash
+orig_rb_mark_hash(tbl)
+#else
rb_mark_hash(tbl)
+#endif
st_table *tbl;
{
+#ifndef OPT_GC
if (!tbl) return;
+#endif
st_foreach(tbl, mark_keyvalue, 0);
}
+
#define mark_hash(tbl) rb_mark_hash(tbl)
void
@@ -1377,13 +1401,18 @@ rb_gc_mark_maybe(obj)
}
void
+#ifdef rb_gc_mark
+orig_rb_gc_mark(ptr)
+#else
rb_gc_mark(ptr)
+#endif
VALUE ptr;
{
RVALUE *obj = RANY(ptr);
SET_STACK_END;
-
+#ifndef OPT_GC
if (rb_special_const_p(ptr)) return; /* special const not marked */
+#endif
if (obj->as.basic.flags == 0) return; /* free cell */
if (rb_mark_table_contains(obj)) return; /* already marked */
rb_mark_table_add(obj);
@@ -1400,7 +1429,6 @@ gc_mark_children(ptr)
VALUE ptr;
{
RVALUE *obj = RANY(ptr);
-
goto marking; /* skip */
again:
@@ -1636,8 +1664,9 @@ gc_mark_children(ptr)
{
VALUE *ptr = obj->as.rstruct.ptr;
VALUE *pend = ptr + obj->as.rstruct.len;
- while (ptr < pend)
- gc_mark(*ptr++);
+ while (ptr < pend){
+ gc_mark(*ptr++);
+ }
}
break;
@@ -2670,13 +2699,18 @@ define_final(argc, argv, os)
}
void
+#ifdef rb_gc_copy_finalizer
+orig_rb_gc_copy_finalizer(dest, obj)
+#else
rb_gc_copy_finalizer(dest, obj)
+#endif
VALUE dest, obj;
{
VALUE table;
-
+#ifndef OPT_GC
if (!finalizer_table) return;
if (!FL_TEST(obj, FL_FINALIZE)) return;
+#endif
if (st_lookup(finalizer_table, obj, &table)) {
st_insert(finalizer_table, dest, table);
}
diff --git a/hash.c b/hash.c
index 8086e22..c1e22f2 100644
--- a/hash.c
+++ b/hash.c
@@ -59,7 +59,9 @@ rb_any_cmp(a, b)
{
VALUE args[2];
+#ifndef OPT_HASH
if (a == b) return 0;
+#endif
if (FIXNUM_P(a) && FIXNUM_P(b)) {
return a != b;
}
@@ -76,6 +78,11 @@ rb_any_cmp(a, b)
args[1] = b;
return !rb_with_disable_interrupt(eql, (VALUE)args);
}
+#ifdef OPT_HASH
+#define rb_any_cmp(a,b) \
+ ({ VALUE _a = (a), _b = (b); \
+ _a == _b ? 0 : rb_any_cmp(_a,_b); })
+#endif
VALUE
rb_hash(obj)
@@ -141,13 +148,21 @@ foreach_safe_i(key, value, arg)
{
int status;
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
status = (*arg->func)(key, value, arg->arg);
if (status == ST_CONTINUE) {
return ST_CHECK;
}
return status;
}
+#ifdef OPT_HASH
+#define foreach_safe_i(key, value, arg) \
+ ({ st_data_t _key = (key), _value = (value); \
+ struct foreach_safe_arg * _arg = (arg); \
+ _key == Qundef ? ST_CONTINUE : foreach_safe_i(_key, _value, _arg); })
+#endif
void
st_foreach_safe(table, func, a)
@@ -182,7 +197,9 @@ hash_foreach_iter(key, value, arg)
st_table *tbl;
tbl = RHASH(arg->hash)->tbl;
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
status = (*arg->func)(key, value, arg->arg);
if (RHASH(arg->hash)->tbl != tbl) {
rb_raise(rb_eRuntimeError, "rehash occurred during iteration");
@@ -199,6 +216,13 @@ hash_foreach_iter(key, value, arg)
return ST_CHECK;
}
+#ifdef OPT_HASH
+#define hash_foreach_iter(key, value, arg) \
+ ({ st_data_t _key = (key), _value = (value); \
+ struct foreach_safe_arg * _arg = (arg); \
+ _key == Qundef ? ST_CONTINUE : hash_foreach_iter(_key, _value, _arg); })
+#endif
+
static VALUE
hash_foreach_ensure(hash)
VALUE hash;
@@ -753,24 +777,42 @@ shift_i(key, value, var)
VALUE key, value;
struct shift_var *var;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (var->key != Qundef) return ST_STOP;
var->key = key;
var->val = value;
return ST_DELETE;
}
+#ifdef OPT_HASH
+#define shift_i(key, value, var) \
+({ VALUE _key = (key), _value = (value); \
+ struct shift_var * _var = (var); \
+ _key == Qundef ? ST_CONTINUE : shift_i(_key, _value, _var); })
+#endif
+
static int
shift_i_safe(key, value, var)
VALUE key, value;
struct shift_var *var;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
var->key = key;
var->val = value;
return ST_STOP;
}
+#ifdef OPT_HASH
+#define shift_i_safe(key, value, var) \
+ ({ VALUE _key = (key), _value = (value); \
+ struct shift_var * _var = (var); \
+ _key == Qundef ? ST_CONTINUE : shift_i_safe(_key, _value, _var); })
+#endif
+
/*
* call-seq:
* hsh.shift -> anArray or obj
@@ -820,13 +862,21 @@ static int
delete_if_i(key, value, hash)
VALUE key, value, hash;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (RTEST(rb_yield_values(2, key, value))) {
rb_hash_delete_key(hash, key);
}
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define delete_if_i(key, value, hash) \
+ ({ VALUE _key = (key), _value = (value), _hash = (hash); \
+ _key == Qundef ? ST_CONTINUE : delete_if_i(_key, _value, _hash); })
+#endif
+
/*
* call-seq:
* hsh.delete_if {| key, value | block } -> hsh
@@ -891,12 +941,20 @@ static int
select_i(key, value, result)
VALUE key, value, result;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (RTEST(rb_yield_values(2, key, value)))
rb_ary_push(result, rb_assoc_new(key, value));
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define select_i(key, value, result) \
+ ({ VALUE _key = (key), _value = (value), _result = (result); \
+ _key == Qundef ? ST_CONTINUE : select_i(_key, _value, _result); })
+#endif
+
/*
* call-seq:
* hsh.values_at(key, ...) => array
@@ -1096,11 +1154,19 @@ static int
each_value_i(key, value)
VALUE key, value;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_yield(value);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define each_value_i(key, value) \
+ ({ VALUE _key = (key), _value = (value); \
+ _key == Qundef ? ST_CONTINUE : each_value_i(_key, _value); })
+#endif
+
/*
* call-seq:
* hsh.each_value {| value | block } -> hsh
@@ -1130,11 +1196,19 @@ static int
each_key_i(key, value)
VALUE key, value;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_yield(key);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define each_key_i(key, value) \
+ ({ VALUE _key = (key), _value = (value); \
+ _key == Qundef ? ST_CONTINUE : each_key_i(_key, _value); })
+#endif
+
/*
* call-seq:
* hsh.each_key {| key | block } -> hsh
@@ -1163,11 +1237,19 @@ static int
each_pair_i(key, value)
VALUE key, value;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_yield_values(2, key, value);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define each_pair_i(key, value) \
+ ({ VALUE _key = (key), _value = (value); \
+ _key == Qundef ? ST_CONTINUE : each_pair_i(_key, _value); })
+#endif
+
/*
* call-seq:
* hsh.each_pair {| key_value_array | block } -> hsh
@@ -1198,11 +1280,19 @@ static int
each_i(key, value)
VALUE key, value;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_yield(rb_assoc_new(key, value));
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define each_i(key, value) \
+ ({ VALUE _key = (key), _value = (value); \
+ _key == Qundef ? ST_CONTINUE : each_i(_key, _value); })
+#endif
+
/*
* call-seq:
* hsh.each {| key, value | block } -> hsh
@@ -1236,11 +1326,19 @@ static int
to_a_i(key, value, ary)
VALUE key, value, ary;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_ary_push(ary, rb_assoc_new(key, value));
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define to_a_i(key, value, ary) \
+ ({ VALUE _key = (key), _value = (value), _ary = (ary); \
+ _key == Qundef ? ST_CONTINUE : to_a_i(_key, _value, _ary); })
+#endif
+
/*
* call-seq:
* hsh.to_a -> array
@@ -1387,11 +1485,19 @@ static int
keys_i(key, value, ary)
VALUE key, value, ary;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_ary_push(ary, key);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define keys_i(key, value, ary) \
+ ({ VALUE _key = (key), _value = (value), _ary = (ary); \
+ _key == Qundef ? ST_CONTINUE : keys_i(_key, _value, _ary); })
+#endif
+
/*
* call-seq:
* hsh.keys => array
@@ -1420,11 +1526,19 @@ static int
values_i(key, value, ary)
VALUE key, value, ary;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_ary_push(ary, value);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define values_i(key, value, ary) \
+ ({ VALUE _key = (key), _value = (value), _ary = (ary); \
+ _key == Qundef ? ST_CONTINUE : values_i(_key, _value, _ary); })
+#endif
+
/*
* call-seq:
* hsh.values => array
@@ -1479,7 +1593,9 @@ static int
rb_hash_search_value(key, value, data)
VALUE key, value, *data;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (rb_equal(value, data[1])) {
data[0] = Qtrue;
return ST_STOP;
@@ -1487,6 +1603,13 @@ rb_hash_search_value(key, value, data)
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define rb_hash_search_value(key, value, data) \
+ ({ VALUE _key = (key), _value = (value); \
+ (void) * _data = (data); \
+ _key == Qundef ? ST_CONTINUE : rb_hash_search_value(_key, _value, _data); })
+#endif
+
/*
* call-seq:
* hsh.has_value?(value) => true or false
@@ -1527,7 +1650,9 @@ eql_i(key, val1, data)
{
VALUE val2;
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (!st_lookup(data->tbl, key, &val2)) {
data->result = Qfalse;
return ST_STOP;
@@ -1539,6 +1664,13 @@ eql_i(key, val1, data)
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define eql_i(key, val1, data) \
+ ({ VALUE _key = (key), _val1 = (val1); \
+ struct equal_data * _data = (data); \
+ _key == Qundef ? ST_CONTINUE : eql_i(_key, _val1, _data); })
+#endif
+
static VALUE recursive_eql _((VALUE, VALUE, int));
static VALUE
recursive_eql(hash, dt, recur)
@@ -1548,7 +1680,9 @@ recursive_eql(hash, dt, recur)
{
struct equal_data *data;
+#ifndef OPT_HASH
if (recur) return Qfalse;
+#endif
data = (struct equal_data*)dt;
data->result = Qtrue;
rb_hash_foreach(hash, eql_i, (st_data_t)data);
@@ -1556,6 +1690,13 @@ recursive_eql(hash, dt, recur)
return data->result;
}
+#ifdef OPT_HASH
+#define recursive_eql(hash, dt, recur) \
+ ({ VALUE _hash = (hash), _dt = (dt); \
+ int _recur = (recur); \
+ _recur ? Qfalse : recursive_eql(_hash, _dt, _recur); })
+#endif
+
static VALUE
hash_equal(hash1, hash2, eql)
VALUE hash1, hash2;
@@ -1563,7 +1704,9 @@ hash_equal(hash1, hash2, eql)
{
struct equal_data data;
+#ifndef OPT_HASH
if (hash1 == hash2) return Qtrue;
+#endif
if (TYPE(hash2) != T_HASH) {
if (!rb_respond_to(hash2, rb_intern("to_hash"))) {
return Qfalse;
@@ -1583,6 +1726,13 @@ hash_equal(hash1, hash2, eql)
return rb_exec_recursive(recursive_eql, hash1, (VALUE)&data);
}
+#ifdef OPT_HASH
+#define hash_equal(hash1, hash2, eql) \
+ ({ VALUE _hash1 = (hash1), _hash2 = (hash2); \
+ int _eql = (eql); \
+ _hash1 == _hash2 ? Qtrue : hash_equal(_hash1, _hash2, _eql); })
+#endif
+
/*
* call-seq:
* hsh == other_hash => true or false
@@ -1615,12 +1765,21 @@ hash_i(key, val, hval)
VALUE val;
int *hval;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
*hval ^= rb_hash(key);
*hval ^= rb_hash(val);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define hash_i(key, val, hval) \
+ ({ VALUE _key = (key), _val = (val); \
+ int * _hval = (hval); \
+ _key == Qundef ? ST_CONTINUE : hash_i(_key, _val, _hval); })
+#endif
+
static VALUE recursive_hash _((VALUE, VALUE, int));
static VALUE
recursive_hash(hash, dummy, recur)
@@ -1674,11 +1833,19 @@ rb_hash_invert_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_hash_aset(hash, value, key);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define rb_hash_invert_i(key, value, hash) \
+ ({ VALUE _key = (key), _value = (value), _hash = (hash); \
+ _key == Qundef ? ST_CONTINUE : rb_hash_invert_i(_key, _value, _hash); })
+#endif
+
/*
* call-seq:
* hsh.invert -> aHash
@@ -1706,17 +1873,27 @@ rb_hash_update_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
rb_hash_aset(hash, key, value);
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define rb_hash_update_i(key, value, hash) \
+ ({ VALUE _key = (key), _value = (value), _hash = (hash); \
+ _key == Qundef ? ST_CONTINUE : rb_hash_update_i(_key, _value, _hash); })
+#endif
+
static int
rb_hash_update_block_i(key, value, hash)
VALUE key, value;
VALUE hash;
{
+#ifndef OPT_HASH
if (key == Qundef) return ST_CONTINUE;
+#endif
if (rb_hash_has_key(hash, key)) {
value = rb_yield_values(3, key, rb_hash_aref(hash, key), value);
}
@@ -1724,6 +1901,12 @@ rb_hash_update_block_i(key, value, hash)
return ST_CONTINUE;
}
+#ifdef OPT_HASH
+#define rb_hash_update_block_i(key, value, hash) \
+ ({ VALUE _key = (key), _value = (value), _hash = (hash); \
+ _key == Qundef ? ST_CONTINUE : rb_hash_update_block_i(_key, _value, _hash); })
+#endif
+
/*
* call-seq:
* hsh.merge!(other_hash) => hsh
@@ -1819,10 +2002,18 @@ static VALUE
env_str_new2(ptr)
const char *ptr;
{
+#ifndef OPT_HASH
if (!ptr) return Qnil;
+#endif
return env_str_new(ptr, strlen(ptr));
}
+#ifdef OPT_HASH
+#define env_str_new2(ptr) \
+ ({ const char * _ptr = (ptr); \
+ !_ptr ? Qnil : env_str_new2(_ptr); })
+#endif
+
static VALUE
env_delete(obj, name)
VALUE obj, name;
@@ -2597,7 +2788,9 @@ env_replace(env, hash)
long i;
keys = env_keys(); /* rb_secure(4); */
+#ifndef OPT_HASH
if (env == hash) return env;
+#endif
hash = to_hash(hash);
rb_hash_foreach(hash, env_replace_i, keys);
@@ -2607,6 +2800,12 @@ env_replace(env, hash)
return env;
}
+#ifdef OPT_HASH
+#define env_replace(env, hash) \
+ ({ VALUE _env = (env), _hash = (hash); \
+ _env == _hash ? _env : env_replace(_env, _hash); })
+#endif
+
static int
env_update_i(key, val)
VALUE key, val;
diff --git a/intern.h b/intern.h
index 71264fe..b0ea3c7 100644
--- a/intern.h
+++ b/intern.h
@@ -31,21 +31,17 @@ VALUE rb_ary_freeze _((VALUE));
VALUE rb_ary_aref _((int, VALUE*, VALUE));
void rb_ary_store _((VALUE, long, VALUE));
VALUE rb_ary_dup _((VALUE));
-VALUE rb_ary_to_ary _((VALUE));
-VALUE rb_ary_to_s _((VALUE));
VALUE rb_ary_push _((VALUE, VALUE));
VALUE rb_ary_pop _((VALUE));
VALUE rb_ary_shift _((VALUE));
VALUE rb_ary_unshift _((VALUE, VALUE));
VALUE rb_ary_entry _((VALUE, long));
VALUE rb_ary_each _((VALUE));
-VALUE rb_ary_join _((VALUE, VALUE));
VALUE rb_ary_print_on _((VALUE, VALUE));
VALUE rb_ary_reverse _((VALUE));
VALUE rb_ary_sort _((VALUE));
VALUE rb_ary_sort_bang _((VALUE));
VALUE rb_ary_delete _((VALUE, VALUE));
-VALUE rb_ary_delete_at _((VALUE, long));
VALUE rb_ary_clear _((VALUE));
VALUE rb_ary_plus _((VALUE, VALUE));
VALUE rb_ary_concat _((VALUE, VALUE));
@@ -63,8 +59,6 @@ void rb_big_2comp _((VALUE));
VALUE rb_big_norm _((VALUE));
VALUE rb_uint2big _((unsigned long));
VALUE rb_int2big _((long));
-VALUE rb_uint2inum _((unsigned long));
-VALUE rb_int2inum _((long));
VALUE rb_cstr_to_inum _((const char*, int, int));
VALUE rb_str_to_inum _((VALUE, int, int));
VALUE rb_cstr2inum _((const char*, int));
@@ -76,8 +70,6 @@ long rb_big2long _((VALUE));
unsigned long rb_big2ulong _((VALUE));
#define rb_big2uint(x) rb_big2ulong(x)
#if HAVE_LONG_LONG
-VALUE rb_ll2inum _((LONG_LONG));
-VALUE rb_ull2inum _((unsigned LONG_LONG));
LONG_LONG rb_big2ll _((VALUE));
unsigned LONG_LONG rb_big2ull _((VALUE));
#endif /* HAVE_LONG_LONG */
@@ -89,7 +81,6 @@ VALUE rb_big_plus _((VALUE, VALUE));
VALUE rb_big_minus _((VALUE, VALUE));
VALUE rb_big_mul _((VALUE, VALUE));
VALUE rb_big_divmod _((VALUE, VALUE));
-VALUE rb_big_pow _((VALUE, VALUE));
VALUE rb_big_and _((VALUE, VALUE));
VALUE rb_big_or _((VALUE, VALUE));
VALUE rb_big_xor _((VALUE, VALUE));
@@ -162,8 +153,6 @@ void rb_remove_method _((VALUE, const char*));
#define HAVE_RB_DEFINE_ALLOC_FUNC 1
void rb_define_alloc_func _((VALUE, VALUE (*)(VALUE)));
void rb_undef_alloc_func _((VALUE));
-void rb_clear_cache _((void));
-void rb_clear_cache_by_class _((VALUE));
void rb_alias _((VALUE, ID, ID));
void rb_attr _((VALUE,ID,int,int,int));
int rb_method_boundp _((VALUE, ID, int));
@@ -207,11 +196,7 @@ NORETURN(void ruby_stop _((int)));
int ruby_cleanup _((int));
int ruby_exec _((void));
void rb_gc_mark_threads _((void));
-void rb_thread_start_timer _((void));
-void rb_thread_stop_timer _((void));
void rb_thread_schedule _((void));
-void rb_thread_wait_fd _((int));
-int rb_thread_fd_writable _((int));
void rb_thread_fd_close _((int));
int rb_thread_alone _((void));
void rb_thread_polling _((void));
@@ -234,7 +219,6 @@ VALUE rb_thread_current _((void));
VALUE rb_thread_main _((void));
VALUE rb_thread_local_aref _((VALUE, ID));
VALUE rb_thread_local_aset _((VALUE, ID, VALUE));
-void rb_thread_atfork _((void));
VALUE rb_exec_recursive _((VALUE(*)(VALUE, VALUE, int),VALUE,VALUE));
VALUE rb_funcall_rescue __((VALUE, ID, int, ...));
/* file.c */
@@ -255,14 +239,9 @@ size_t ruby_stack_length _((VALUE**));
int rb_during_gc _((void));
char *rb_source_filename _((const char*));
void rb_gc_mark_locations _((VALUE*, VALUE*));
-void rb_mark_tbl _((struct st_table*));
-void rb_mark_set _((struct st_table*));
-void rb_mark_hash _((struct st_table*));
void rb_gc_mark_maybe _((VALUE));
-void rb_gc_mark _((VALUE));
void rb_gc_force_recycle _((VALUE));
void rb_gc _((void));
-void rb_gc_copy_finalizer _((VALUE,VALUE));
void rb_gc_finalize_deferred _((void));
void rb_gc_call_finalizer_at_exit _((void));
VALUE rb_gc_enable _((void));
@@ -322,7 +301,6 @@ VALUE rb_num_coerce_bin _((VALUE, VALUE));
VALUE rb_num_coerce_cmp _((VALUE, VALUE));
VALUE rb_num_coerce_relop _((VALUE, VALUE));
VALUE rb_float_new _((double));
-VALUE rb_num2fix _((VALUE));
VALUE rb_fix2str _((VALUE, int));
VALUE rb_dbl_cmp _((double, double));
/* object.c */
@@ -334,7 +312,6 @@ VALUE rb_obj_is_kind_of _((VALUE, VALUE));
VALUE rb_obj_alloc _((VALUE));
VALUE rb_obj_clone _((VALUE));
VALUE rb_obj_dup _((VALUE));
-VALUE rb_obj_init_copy _((VALUE,VALUE));
VALUE rb_obj_taint _((VALUE));
VALUE rb_obj_tainted _((VALUE));
VALUE rb_obj_untaint _((VALUE));
@@ -343,9 +320,6 @@ VALUE rb_obj_id _((VALUE));
VALUE rb_obj_class _((VALUE));
VALUE rb_class_real _((VALUE));
VALUE rb_class_inherited_p _((VALUE, VALUE));
-VALUE rb_convert_type _((VALUE,int,const char*,const char*));
-VALUE rb_check_convert_type _((VALUE,int,const char*,const char*));
-VALUE rb_check_to_integer _((VALUE, const char *));
VALUE rb_to_int _((VALUE));
VALUE rb_Integer _((VALUE));
VALUE rb_Float _((VALUE));
@@ -392,8 +366,6 @@ double rb_genrand_real(void);
int rb_memcmp _((const void*,const void*,long));
int rb_memcicmp _((const void*,const void*,long));
long rb_memsearch _((const void*,long,const void*,long));
-VALUE rb_reg_nth_defined _((int, VALUE));
-VALUE rb_reg_nth_match _((int, VALUE));
VALUE rb_reg_last_match _((VALUE));
VALUE rb_reg_match_pre _((VALUE));
VALUE rb_reg_match_post _((VALUE));
@@ -435,7 +407,6 @@ VALUE rb_str_format _((int, VALUE*, VALUE));
VALUE rb_str_new _((const char*, long));
VALUE rb_str_new2 _((const char*));
VALUE rb_str_new3 _((VALUE));
-VALUE rb_str_new4 _((VALUE));
VALUE rb_str_new5 _((VALUE, const char*, long));
VALUE rb_tainted_str_new _((const char*, long));
VALUE rb_tainted_str_new2 _((const char*));
@@ -443,9 +414,7 @@ VALUE rb_str_buf_new _((long));
VALUE rb_str_buf_new2 _((const char*));
VALUE rb_str_tmp_new _((long));
VALUE rb_str_buf_append _((VALUE, VALUE));
-VALUE rb_str_buf_cat _((VALUE, const char*, long));
VALUE rb_str_buf_cat2 _((VALUE, const char*));
-VALUE rb_obj_as_string _((VALUE));
VALUE rb_check_string_type _((VALUE));
VALUE rb_str_dup _((VALUE));
VALUE rb_str_locktmp _((VALUE));
@@ -453,8 +422,6 @@ VALUE rb_str_unlocktmp _((VALUE));
VALUE rb_str_dup_frozen _((VALUE));
VALUE rb_str_plus _((VALUE, VALUE));
VALUE rb_str_times _((VALUE, VALUE));
-VALUE rb_str_substr _((VALUE, long, long));
-void rb_str_modify _((VALUE));
VALUE rb_str_freeze _((VALUE));
void rb_str_set_len _((VALUE, long));
VALUE rb_str_resize _((VALUE, long));
@@ -469,8 +436,6 @@ void rb_str_update _((VALUE, long, long, VALUE));
VALUE rb_str_inspect _((VALUE));
VALUE rb_str_dump _((VALUE));
VALUE rb_str_split _((VALUE, const char*));
-void rb_str_associate _((VALUE, VALUE));
-VALUE rb_str_associated _((VALUE));
void rb_str_setter _((VALUE, ID, VALUE*));
VALUE rb_str_intern _((VALUE));
/* struct.c */
@@ -495,16 +460,10 @@ VALUE rb_class_name _((VALUE));
void rb_autoload _((VALUE, ID, const char*));
VALUE rb_autoload_load _((VALUE, ID));
VALUE rb_autoload_p _((VALUE, ID));
-void rb_gc_mark_global_tbl _((void));
VALUE rb_f_trace_var _((int, VALUE*));
VALUE rb_f_untrace_var _((int, VALUE*));
VALUE rb_f_global_variables _((void));
void rb_alias_variable _((ID, ID));
-struct st_table* rb_generic_ivar_table _((VALUE));
-void rb_copy_generic_ivar _((VALUE,VALUE));
-void rb_mark_generic_ivar _((VALUE));
-void rb_mark_generic_ivar_tbl _((void));
-void rb_free_generic_ivar _((VALUE));
VALUE rb_ivar_get _((VALUE, ID));
VALUE rb_ivar_set _((VALUE, ID, VALUE));
VALUE rb_ivar_defined _((VALUE, ID));
@@ -515,7 +474,6 @@ VALUE rb_obj_instance_variables _((VALUE));
VALUE rb_obj_remove_instance_variable _((VALUE, VALUE));
void *rb_mod_const_at _((VALUE, void*));
void *rb_mod_const_of _((VALUE, void*));
-VALUE rb_const_list _((void*));
VALUE rb_mod_constants _((VALUE));
VALUE rb_mod_remove_const _((VALUE, VALUE));
int rb_const_defined _((VALUE, ID));
diff --git a/lex.c b/lex.c
index a15309d..0008a06 100644
--- a/lex.c
+++ b/lex.c
@@ -1,13 +1,42 @@
-/* C code produced by gperf version 2.7.2 */
-/* Command-line: gperf -p -j1 -i 1 -g -o -t -N rb_reserved_word -k'1,3,$' ./keywords */
+/* C code produced by gperf version 3.0.4 */
+/* Command-line: gperf -C -p -j1 -i 1 -g -o -t -N rb_reserved_word -k'1,3,$' keywords */
+
+#if !((' ' == 32) && ('!' == 33) && ('"' == 34) && ('#' == 35) \
+ && ('%' == 37) && ('&' == 38) && ('\'' == 39) && ('(' == 40) \
+ && (')' == 41) && ('*' == 42) && ('+' == 43) && (',' == 44) \
+ && ('-' == 45) && ('.' == 46) && ('/' == 47) && ('0' == 48) \
+ && ('1' == 49) && ('2' == 50) && ('3' == 51) && ('4' == 52) \
+ && ('5' == 53) && ('6' == 54) && ('7' == 55) && ('8' == 56) \
+ && ('9' == 57) && (':' == 58) && (';' == 59) && ('<' == 60) \
+ && ('=' == 61) && ('>' == 62) && ('?' == 63) && ('A' == 65) \
+ && ('B' == 66) && ('C' == 67) && ('D' == 68) && ('E' == 69) \
+ && ('F' == 70) && ('G' == 71) && ('H' == 72) && ('I' == 73) \
+ && ('J' == 74) && ('K' == 75) && ('L' == 76) && ('M' == 77) \
+ && ('N' == 78) && ('O' == 79) && ('P' == 80) && ('Q' == 81) \
+ && ('R' == 82) && ('S' == 83) && ('T' == 84) && ('U' == 85) \
+ && ('V' == 86) && ('W' == 87) && ('X' == 88) && ('Y' == 89) \
+ && ('Z' == 90) && ('[' == 91) && ('\\' == 92) && (']' == 93) \
+ && ('^' == 94) && ('_' == 95) && ('a' == 97) && ('b' == 98) \
+ && ('c' == 99) && ('d' == 100) && ('e' == 101) && ('f' == 102) \
+ && ('g' == 103) && ('h' == 104) && ('i' == 105) && ('j' == 106) \
+ && ('k' == 107) && ('l' == 108) && ('m' == 109) && ('n' == 110) \
+ && ('o' == 111) && ('p' == 112) && ('q' == 113) && ('r' == 114) \
+ && ('s' == 115) && ('t' == 116) && ('u' == 117) && ('v' == 118) \
+ && ('w' == 119) && ('x' == 120) && ('y' == 121) && ('z' == 122) \
+ && ('{' == 123) && ('|' == 124) && ('}' == 125) && ('~' == 126))
+/* The character set is not based on ISO-646. */
+error "gperf generated tables don't work with this execution character set. Please report a bug to <[email protected]>."
+#endif
+
+#line 1 "keywords"
struct kwtable {const char *name; int id[2]; enum lex_state state;};
#define TOTAL_KEYWORDS 40
#define MIN_WORD_LENGTH 2
#define MAX_WORD_LENGTH 8
#define MIN_HASH_VALUE 6
-#define MAX_HASH_VALUE 55
-/* maximum key range = 50, duplicates = 0 */
+#define MAX_HASH_VALUE 50
+/* maximum key range = 45, duplicates = 0 */
#ifdef __GNUC__
__inline
@@ -21,42 +50,42 @@ hash (str, len)
register const char *str;
register unsigned int len;
{
- static unsigned char asso_values[] =
+ static const unsigned char asso_values[] =
{
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 11, 56, 56, 36, 56, 1, 37,
- 31, 1, 56, 56, 56, 56, 29, 56, 1, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 1, 56, 32, 1, 2,
- 1, 1, 4, 23, 56, 17, 56, 20, 9, 2,
- 9, 26, 14, 56, 5, 1, 1, 16, 56, 21,
- 20, 9, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56, 56, 56, 56, 56,
- 56, 56, 56, 56, 56, 56
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 23, 51, 51, 13, 51, 1, 1,
+ 11, 12, 51, 51, 51, 51, 10, 51, 12, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 11, 51, 13, 1, 26,
+ 4, 1, 8, 28, 51, 23, 51, 1, 1, 27,
+ 5, 19, 21, 51, 8, 3, 3, 11, 51, 21,
+ 24, 16, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51, 51, 51, 51, 51,
+ 51, 51, 51, 51, 51, 51
};
register int hval = len;
switch (hval)
{
default:
- case 3:
hval += asso_values[(unsigned char)str[2]];
+ /*FALLTHROUGH*/
case 2:
case 1:
hval += asso_values[(unsigned char)str[0]];
@@ -67,57 +96,101 @@ hash (str, len)
#ifdef __GNUC__
__inline
+#if defined __GNUC_STDC_INLINE__ || defined __GNUC_GNU_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
-struct kwtable *
+const struct kwtable *
rb_reserved_word (str, len)
register const char *str;
register unsigned int len;
{
- static struct kwtable wordlist[] =
+ static const struct kwtable wordlist[] =
{
{""}, {""}, {""}, {""}, {""}, {""},
- {"end", {kEND, kEND}, EXPR_END},
+#line 6 "keywords"
+ {"END", {klEND, klEND}, EXPR_END},
+ {""},
+#line 10 "keywords"
+ {"break", {kBREAK, kBREAK}, EXPR_MID},
+#line 16 "keywords"
{"else", {kELSE, kELSE}, EXPR_BEG},
- {"case", {kCASE, kCASE}, EXPR_BEG},
+#line 26 "keywords"
+ {"nil", {kNIL, kNIL}, EXPR_END},
+#line 19 "keywords"
{"ensure", {kENSURE, kENSURE}, EXPR_BEG},
- {"module", {kMODULE, kMODULE}, EXPR_BEG},
- {"elsif", {kELSIF, kELSIF}, EXPR_BEG},
- {"def", {kDEF, kDEF}, EXPR_FNAME},
- {"rescue", {kRESCUE, kRESCUE_MOD}, EXPR_MID},
- {"not", {kNOT, kNOT}, EXPR_BEG},
+#line 18 "keywords"
+ {"end", {kEND, kEND}, EXPR_END},
+#line 35 "keywords"
{"then", {kTHEN, kTHEN}, EXPR_BEG},
- {"yield", {kYIELD, kYIELD}, EXPR_ARG},
- {"for", {kFOR, kFOR}, EXPR_BEG},
- {"self", {kSELF, kSELF}, EXPR_END},
+#line 27 "keywords"
+ {"not", {kNOT, kNOT}, EXPR_BEG},
+#line 20 "keywords"
{"false", {kFALSE, kFALSE}, EXPR_END},
- {"retry", {kRETRY, kRETRY}, EXPR_END},
- {"return", {kRETURN, kRETURN}, EXPR_MID},
+#line 33 "keywords"
+ {"self", {kSELF, kSELF}, EXPR_END},
+#line 17 "keywords"
+ {"elsif", {kELSIF, kELSIF}, EXPR_BEG},
+#line 30 "keywords"
+ {"rescue", {kRESCUE, kRESCUE_MOD}, EXPR_MID},
+#line 36 "keywords"
{"true", {kTRUE, kTRUE}, EXPR_END},
- {"if", {kIF, kIF_MOD}, EXPR_BEG},
- {"defined?", {kDEFINED, kDEFINED}, EXPR_ARG},
- {"super", {kSUPER, kSUPER}, EXPR_ARG},
- {"undef", {kUNDEF, kUNDEF}, EXPR_FNAME},
- {"break", {kBREAK, kBREAK}, EXPR_MID},
- {"in", {kIN, kIN}, EXPR_BEG},
- {"do", {kDO, kDO}, EXPR_BEG},
- {"nil", {kNIL, kNIL}, EXPR_END},
+#line 39 "keywords"
{"until", {kUNTIL, kUNTIL_MOD}, EXPR_BEG},
+#line 38 "keywords"
{"unless", {kUNLESS, kUNLESS_MOD}, EXPR_BEG},
+#line 32 "keywords"
+ {"return", {kRETURN, kRETURN}, EXPR_MID},
+#line 13 "keywords"
+ {"def", {kDEF, kDEF}, EXPR_FNAME},
+#line 8 "keywords"
+ {"and", {kAND, kAND}, EXPR_BEG},
+#line 15 "keywords"
+ {"do", {kDO, kDO}, EXPR_BEG},
+#line 42 "keywords"
+ {"yield", {kYIELD, kYIELD}, EXPR_ARG},
+#line 21 "keywords"
+ {"for", {kFOR, kFOR}, EXPR_BEG},
+#line 37 "keywords"
+ {"undef", {kUNDEF, kUNDEF}, EXPR_FNAME},
+#line 28 "keywords"
{"or", {kOR, kOR}, EXPR_BEG},
- {"next", {kNEXT, kNEXT}, EXPR_MID},
+#line 23 "keywords"
+ {"in", {kIN, kIN}, EXPR_BEG},
+#line 40 "keywords"
{"when", {kWHEN, kWHEN}, EXPR_BEG},
+#line 31 "keywords"
+ {"retry", {kRETRY, kRETRY}, EXPR_END},
+#line 22 "keywords"
+ {"if", {kIF, kIF_MOD}, EXPR_BEG},
+#line 11 "keywords"
+ {"case", {kCASE, kCASE}, EXPR_BEG},
+#line 29 "keywords"
{"redo", {kREDO, kREDO}, EXPR_END},
- {"and", {kAND, kAND}, EXPR_BEG},
+#line 25 "keywords"
+ {"next", {kNEXT, kNEXT}, EXPR_MID},
+#line 34 "keywords"
+ {"super", {kSUPER, kSUPER}, EXPR_ARG},
+#line 24 "keywords"
+ {"module", {kMODULE, kMODULE}, EXPR_BEG},
+#line 9 "keywords"
{"begin", {kBEGIN, kBEGIN}, EXPR_BEG},
+#line 3 "keywords"
{"__LINE__", {k__LINE__, k__LINE__}, EXPR_END},
- {"class", {kCLASS, kCLASS}, EXPR_CLASS},
+#line 4 "keywords"
{"__FILE__", {k__FILE__, k__FILE__}, EXPR_END},
- {"END", {klEND, klEND}, EXPR_END},
+#line 5 "keywords"
{"BEGIN", {klBEGIN, klBEGIN}, EXPR_END},
- {"while", {kWHILE, kWHILE_MOD}, EXPR_BEG},
- {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""}, {""},
- {""},
- {"alias", {kALIAS, kALIAS}, EXPR_FNAME}
+#line 14 "keywords"
+ {"defined?", {kDEFINED, kDEFINED}, EXPR_ARG},
+#line 7 "keywords"
+ {"alias", {kALIAS, kALIAS}, EXPR_FNAME},
+ {""}, {""},
+#line 12 "keywords"
+ {"class", {kCLASS, kCLASS}, EXPR_CLASS},
+ {""}, {""},
+#line 41 "keywords"
+ {"while", {kWHILE, kWHILE_MOD}, EXPR_BEG}
};
if (len <= MAX_WORD_LENGTH && len >= MIN_WORD_LENGTH)
diff --git a/marshal.c b/marshal.c
index 0112257..34b81c3 100644
--- a/marshal.c
+++ b/marshal.c
@@ -930,7 +930,9 @@ r_bytes0(len, arg)
{
VALUE str;
+#ifndef OPT_MARSHAL
if (len == 0) return rb_str_new(0, 0);
+#endif
if (TYPE(arg->src) == T_STRING) {
if (RSTRING(arg->src)->len - arg->offset >= len) {
str = rb_str_new(RSTRING(arg->src)->ptr+arg->offset, len);
@@ -954,6 +956,13 @@ r_bytes0(len, arg)
return str;
}
+#ifdef OPT_MARSHAL
+#define r_bytes0(len, arg) \
+ ({ long _len = (len); \
+ struct load_arg *_arg = (arg); \
+ _len == 0 ? rb_str_new(0, 0) : r_bytes0(_len, _arg); })
+#endif
+
static ID
r_symlink(arg)
struct load_arg *arg;
diff --git a/numeric.c b/numeric.c
index 634c2eb..2c0e058 100644
--- a/numeric.c
+++ b/numeric.c
@@ -837,10 +837,18 @@ static VALUE
num_equal(x, y)
VALUE x, y;
{
+#ifndef OPT_NUMERIC
if (x == y) return Qtrue;
+#endif
return rb_funcall(y, id_eq, 1, x);
}
+#ifdef OPT_NUMERIC
+#define num_equal(x, y) \
+ ({ VALUE _x = (x), _y = (y); \
+ _x == _y ? Qtrue : num_equal(_x, _y); })
+#endif
+
/*
* call-seq:
* flt == obj => true or false
@@ -1584,6 +1592,7 @@ rb_num2long(val)
}
}
+#ifndef OPT_NUMERIC
unsigned long
rb_num2ulong(val)
VALUE val;
@@ -1593,6 +1602,7 @@ rb_num2ulong(val)
}
return (unsigned long)rb_num2long(val);
}
+#endif
#if SIZEOF_INT < SIZEOF_LONG
static void
@@ -1663,20 +1673,26 @@ rb_num2uint(val)
}
unsigned long
+#ifdef rb_fix2uint
+orig_rb_fix2uint(val)
+#else
rb_fix2uint(val)
+#endif
VALUE val;
{
unsigned long num;
-
+#ifndef OPT_NUMERIC
if (!FIXNUM_P(val)) {
return rb_num2uint(val);
}
+#endif
num = FIX2ULONG(val);
check_uint(num, rb_funcall(val, '<', 1, INT2FIX(0)));
return num;
}
#else
+#ifndef OPT_NUMERIC
long
rb_num2int(val)
VALUE val;
@@ -1691,14 +1707,21 @@ rb_fix2int(val)
return FIX2INT(val);
}
#endif
+#endif
VALUE
+#ifdef rb_num2fix
+orig_rb_num2fix(val)
+#else
rb_num2fix(val)
+#endif
VALUE val;
{
long v;
+#ifndef OPT_NUMERIC
if (FIXNUM_P(val)) return val;
+#endif
v = rb_num2long(val);
if (!FIXABLE(v))
diff --git a/object.c b/object.c
index ab62cbf..47c26e7 100644
--- a/object.c
+++ b/object.c
@@ -265,10 +265,16 @@ rb_obj_dup(obj)
/* :nodoc: */
VALUE
+#ifdef rb_obj_init_copy
+orig_rb_obj_init_copy(obj, orig)
+#else
rb_obj_init_copy(obj, orig)
+#endif
VALUE obj, orig;
{
+#ifndef OPT_OBJECT
if (obj == orig) return obj;
+#endif
rb_check_frozen(obj);
if (TYPE(obj) != TYPE(orig) || rb_obj_class(obj) != rb_obj_class(orig)) {
rb_raise(rb_eTypeError, "initialize_copy should take same class object");
@@ -344,7 +350,9 @@ inspect_i(id, value, str)
const char *ivname;
/* need not to show internal data */
+#ifndef OPT_OBJECT
if (CLASS_OF(value) == 0) return ST_CONTINUE;
+#endif
if (!rb_is_instance_id(id)) return ST_CONTINUE;
if (RSTRING(str)->ptr[0] == '-') { /* first element */
RSTRING(str)->ptr[0] = '#';
@@ -363,6 +371,13 @@ inspect_i(id, value, str)
return ST_CONTINUE;
}
+#ifdef OPT_OBJECT
+#define inspect_i(id, value, str) \
+ ({ ID _id = (id); \
+ VALUE _value = (value), _str = (str); \
+ CLASS_OF(_value) == 0 ? ST_CONTINUE : inspect_i(_id, _value, _str); })
+#endif
+
static VALUE
inspect_obj(obj, str)
VALUE obj, str;
@@ -2222,14 +2237,20 @@ convert_type(val, tname, method, raise)
}
VALUE
+#ifdef rb_convert_type
+orig_rb_convert_type(val, type, tname, method)
+#else
rb_convert_type(val, type, tname, method)
+#endif
VALUE val;
int type;
const char *tname, *method;
{
VALUE v;
+#ifndef OPT_OBJECT
if (TYPE(val) == type) return val;
+#endif
v = convert_type(val, tname, method, Qtrue);
if (TYPE(v) != type) {
rb_raise(rb_eTypeError, "%s#%s should return %s",
@@ -2239,15 +2260,21 @@ rb_convert_type(val, type, tname, method)
}
VALUE
+#ifdef rb_check_convert_type
+orig_rb_check_convert_type(val, type, tname, method)
+#else
rb_check_convert_type(val, type, tname, method)
+#endif
VALUE val;
int type;
const char *tname, *method;
{
VALUE v;
+#ifndef OPT_OBJECT
/* always convert T_DATA */
if (TYPE(val) == type && type != T_DATA) return val;
+#endif
v = convert_type(val, tname, method, Qfalse);
if (NIL_P(v)) return Qnil;
if (TYPE(v) != type) {
@@ -2257,7 +2284,6 @@ rb_check_convert_type(val, type, tname, method)
return v;
}
-
static VALUE
rb_to_integer(val, method)
VALUE val;
@@ -2272,11 +2298,17 @@ rb_to_integer(val, method)
}
VALUE
+#ifdef rb_check_to_integer
+orig_rb_check_to_integer(VALUE val, const char *method)
+#else
rb_check_to_integer(VALUE val, const char *method)
+#endif
{
VALUE v;
+#ifndef OPT_OBJECT
if (FIXNUM_P(val)) return val;
+#endif
v = convert_type(val, "Integer", method, Qfalse);
if (!rb_obj_is_kind_of(v, rb_cInteger)) {
return Qnil;
@@ -2723,8 +2755,11 @@ Init_Object()
rb_define_method(rb_mKernel, "clone", rb_obj_clone, 0);
rb_define_method(rb_mKernel, "dup", rb_obj_dup, 0);
+#ifdef OPT_OBJECT
+ rb_define_method(rb_mKernel, "initialize_copy", orig_rb_obj_init_copy, 1);
+#else
rb_define_method(rb_mKernel, "initialize_copy", rb_obj_init_copy, 1);
-
+#endif
rb_define_method(rb_mKernel, "taint", rb_obj_taint, 0);
rb_define_method(rb_mKernel, "tainted?", rb_obj_tainted, 0);
rb_define_method(rb_mKernel, "untaint", rb_obj_untaint, 0);
diff --git a/optimizations.h b/optimizations.h
new file mode 100644
index 0000000..2d43a7d
--- /dev/null
+++ b/optimizations.h
@@ -0,0 +1,312 @@
+#ifndef _OPTIMIZATIONS_H_
+#define _OPTIMIZATIONS_H_
+
+#define OPT_ARRAY
+#define OPT_BIGNUM
+#define OPT_CLASS
+#define OPT_EVAL
+#define OPT_GC
+#define OPT_HASH
+#define OPT_NUMERIC
+#define OPT_OBJECT
+#define OPT_REXP
+#define OPT_STRING
+#define OPT_STRUCT
+#define OPT_TIME
+#define OPT_VARIABLE
+#define OPT_UTIL
+#define OPT_ST
+#define OPT_MARSHAL
+#define OPT_PACK
+
+#ifdef OPT_BIGNUM
+VALUE orig_rb_big_pow _((VALUE, VALUE));
+#define rb_uint2inum(n) \
+ ({ unsigned long _n = (n); \
+ POSFIXABLE(_n) ? LONG2FIX(_n) : rb_uint2big(_n); })
+#define rb_int2inum(n) \
+ ({ long _n = (n); \
+ FIXABLE(_n) ? LONG2FIX(_n) : rb_int2big(_n); })
+#if HAVE_LONG_LONG
+#define rb_ull2inum(n) \
+ ({ unsigned long _n = (n); \
+ POSFIXABLE(_n) ? LONG2FIX(_n) : rb_ull2big(_n); })
+#define rb_ll2inum(n) \
+ ({ long _n = (n); \
+ FIXABLE(_n) ? LONG2FIX(_n) : rb_ll2big(_n); })
+#endif
+#define rb_big_pow(x, y) \
+ ({ VALUE _x = (x), _y = (y); \
+ _y == INT2FIX(0) ? INT2FIX(1) : orig_rb_big_pow(_x, _y); })
+#else
+VALUE rb_big_pow _((VALUE, VALUE));
+VALUE rb_uint2inum _((unsigned long));
+VALUE rb_int2inum _((long));
+#if HAVE_LONG_LONG
+VALUE rb_ll2inum _((LONG_LONG));
+VALUE rb_ull2inum _((unsigned LONG_LONG));
+#endif
+#endif
+
+#ifdef OPT_GC
+#include "st.h"
+RUBY_EXTERN st_table *finalizer_table;
+void orig_rb_mark_tbl _((struct st_table*));
+void orig_rb_mark_set _((struct st_table*));
+void orig_rb_mark_hash _((struct st_table*));
+void orig_rb_gc_mark _((VALUE));
+void orig_rb_gc_copy_finalizer _((VALUE,VALUE));
+#define rb_mark_tbl(tbl) \
+ ({ struct st_table* _tbl = (tbl); \
+ if (_tbl) orig_rb_mark_tbl(_tbl); })
+#define rb_mark_set(tbl) \
+ ({ struct st_table* _tbl = (tbl); \
+ if (_tbl) orig_rb_mark_set(_tbl); })
+#define rb_mark_hash(tbl) \
+ ({ struct st_table* _tbl = (tbl); \
+ if (_tbl) orig_rb_mark_hash(_tbl); })
+#define rb_gc_mark(ptr) \
+ ({ VALUE _ptr = (ptr); \
+ if (!rb_special_const_p(_ptr)) orig_rb_gc_mark(_ptr); })
+#define rb_gc_copy_finalizer(dest, obj) \
+ ({ VALUE _dest = (dest), _obj = (obj); \
+ if (finalizer_table || FL_TEST(_obj, FL_FINALIZE)) orig_rb_gc_copy_finalizer(_dest, _obj); })
+#else
+void rb_mark_tbl _((struct st_table*));
+void rb_mark_set _((struct st_table*));
+void rb_mark_hash _((struct st_table*));
+void rb_gc_mark _((VALUE));
+void rb_gc_copy_finalizer _((VALUE,VALUE));
+#endif
+
+#ifdef OPT_STRING
+VALUE orig_rb_obj_as_string _((VALUE));
+VALUE orig_rb_str_substr _((VALUE, long, long));
+VALUE orig_rb_str_new4 _((VALUE));
+void orig_rb_str_associate _((VALUE, VALUE));
+VALUE orig_rb_str_associated _((VALUE));
+VALUE orig_rb_str_buf_cat _((VALUE, const char*, long));
+#define rb_obj_as_string(obj) \
+ ({ VALUE _obj = (obj); \
+ TYPE(_obj) == T_STRING ? _obj : orig_rb_obj_as_string(_obj); })
+#define rb_str_substr(s, b, l) \
+ ({ VALUE _s = (s); \
+ long _b = (b), _l = (l); \
+ _l < 0 || _b > RSTRING((_s))->len ? Qnil : orig_rb_str_substr(_s, _b, _l); })
+#define rb_str_new4(orig) \
+ ({ VALUE _orig = (orig); \
+ OBJ_FROZEN(_orig) ? _orig : orig_rb_str_new4(_orig); })
+#define rb_str_associate(str, add) \
+ ({ VALUE _str = (str), _add = (add); \
+ FL_TEST(_str, FL_USER3) ? rb_ary_concat(RSTRING(_str)->aux.shared, _add) : orig_rb_str_associate(_str, _add); })
+#define rb_str_associated(str) \
+ ({ VALUE _str = (str); \
+ FL_TEST(_str, FL_USER3) ? RSTRING(_str)->aux.shared : orig_rb_str_associated(_str); })
+#define rb_str_buf_cat(str, ptr, len) \
+ ({ VALUE _str = (str); \
+ const char* _ptr = (ptr); \
+ long _len = (len); \
+ _len == 0 ? _str : orig_rb_str_buf_cat(_str, _ptr, _len); })
+int str_independent _((VALUE));
+void str_make_independent _((VALUE));
+#define rb_str_modify(str) \
+ ({ VALUE _str = (str); \
+ if (!str_independent(_str)) str_make_independent(_str); })
+#else
+VALUE rb_obj_as_string _((VALUE));
+VALUE rb_str_substr _((VALUE, long, long));
+VALUE rb_str_new4 _((VALUE));
+void rb_str_associate _((VALUE, VALUE));
+VALUE rb_str_associated _((VALUE));
+VALUE rb_str_buf_cat _((VALUE, const char*, long));
+void rb_str_modify _((VALUE));
+#endif
+
+#ifdef OPT_REXP
+VALUE orig_rb_reg_nth_defined _((int, VALUE));
+VALUE orig_rb_reg_nth_match _((int, VALUE));
+#define rb_reg_nth_defined(nth, match) \
+ ({ int _nth = (nth); \
+ VALUE _match = (match); \
+ NIL_P(_match) ? Qnil : orig_rb_reg_nth_defined(_nth, _match); })
+#define rb_reg_nth_match(nth, match) \
+ ({ int _nth = (nth); \
+ VALUE _match = (match); \
+ NIL_P(_match) ? Qnil : orig_rb_reg_nth_match(_nth, _match); })
+#else
+VALUE rb_reg_nth_defined _((int, VALUE));
+VALUE rb_reg_nth_match _((int, VALUE));
+#endif
+
+#ifdef OPT_ARRAY
+VALUE orig_rb_ary_to_ary _((VALUE));
+VALUE orig_rb_ary_join _((VALUE, VALUE));
+VALUE orig_rb_ary_to_s _((VALUE));
+VALUE orig_rb_ary_delete_at _((VALUE, long));
+#define rb_ary_to_ary(obj) \
+ ({ VALUE _obj = (obj); \
+ TYPE(_obj) == T_ARRAY ? _obj : orig_rb_ary_to_ary(_obj); })
+#define rb_ary_join(ary, sep) \
+ ({ VALUE _ary = (ary); \
+ VALUE _sep = (sep); \
+ RARRAY(_ary)->len == 0 ? rb_str_new(0,0) : orig_rb_ary_join(_ary, _sep); })
+#define rb_ary_to_s(ary) \
+({ VALUE _ary = (ary); \
+ RARRAY(_ary)->len == 0 ? rb_str_new(0, 0) : orig_rb_ary_to_s(_ary); })
+#define rb_ary_delete_at(ary,pos) \
+ ({ VALUE _ary = (ary); \
+ long _pos = (pos); \
+ _pos >= RARRAY(_ary)->len ? Qnil : orig_rb_ary_delete_at(_ary,_pos); })
+#else
+VALUE rb_ary_to_ary _((VALUE));
+VALUE rb_ary_join _((VALUE, VALUE));
+VALUE rb_ary_to_s _((VALUE));
+VALUE rb_ary_delete_at _((VALUE, long));
+#endif
+
+#ifdef OPT_OBJECT
+VALUE orig_rb_obj_init_copy _((VALUE,VALUE));
+VALUE orig_rb_convert_type _((VALUE,int,const char*,const char*));
+VALUE orig_rb_check_convert_type _((VALUE,int,const char*,const char*));
+VALUE orig_rb_check_to_integer _((VALUE, const char *));
+#define rb_obj_init_copy(obj, orig) \
+ ({ VALUE _obj = (obj), _orig = (orig); \
+ _obj == _orig ? _obj : orig_rb_obj_init_copy(_obj, _orig); })
+#define rb_convert_type(val, type, tname, method) \
+({ VALUE _val = (val); \
+ int _type = (type); \
+ const char* _tname = (tname); \
+ const char* _method = (method); \
+ TYPE(_val) == _type ? _val : orig_rb_convert_type(_val, _type, _tname, _method); })
+#define rb_check_convert_type(val, type, tname, method) \
+ ({ VALUE _val = (val); \
+ int _type = (type); \
+ const char* _tname = (tname); \
+ const char* _method = (method); \
+ TYPE(_val) == _type && _type != T_DATA ? _val : orig_rb_check_convert_type(_val, _type, _tname, _method); })
+#define rb_check_to_integer(val, method) \
+ ({ VALUE _val = (val); \
+ const char* _method = (method); \
+ FIXNUM_P(_val) ? _val : orig_rb_check_to_integer(_val, _method); })
+#else
+VALUE rb_obj_init_copy _((VALUE,VALUE));
+VALUE rb_convert_type _((VALUE,int,const char*,const char*));
+VALUE rb_check_convert_type _((VALUE,int,const char*,const char*));
+VALUE rb_check_to_integer _((VALUE, const char *));
+#endif
+
+#ifdef OPT_EVAL
+#include "node.h"
+RUBY_EXTERN int ruby_running;
+RUBY_EXTERN int thread_init;
+RUBY_EXTERN int ruby_in_compile;
+RUBY_EXTERN rb_thread_t rb_curr_thread;
+#define curr_thread rb_curr_thread
+void orig_rb_clear_cache _((void));
+void orig_rb_clear_cache_by_class _((VALUE));
+void orig_rb_thread_wait_fd _((int));
+int orig_rb_thread_fd_writable _((int));
+void orig_rb_thread_start_timer _((void));
+void orig_rb_thread_stop_timer _((void));
+void orig_rb_thread_atfork _((void));
+#define rb_clear_cache() \
+ ({if (ruby_running) orig_rb_clear_cache(); })
+#define rb_clear_cache_by_class(klass) \
+ ({ VALUE _klass = (klass); \
+ if (ruby_running) orig_rb_clear_cache_by_class(_klass); })
+#define rb_thread_wait_fd(fd) \
+ ({ int _fd = (fd); \
+ (rb_thread_critical || ruby_in_compile || curr_thread == curr_thread->next) ? NULL : orig_rb_thread_wait_fd(_fd); })
+#define rb_thread_fd_writable(fd) \
+ ({ int _fd = (fd); \
+ (rb_thread_critical || curr_thread == curr_thread->next) ? Qtrue : orig_rb_thread_fd_writable(_fd); })
+#if defined(_THREAD_SAFE)
+#define rb_thread_start_timer() \
+ ({ if (!thread_init || !rb_thread_alone()) orig_rb_thread_start_timer(); })
+#define rb_thread_stop_timer() \
+ ({ if (thread_init) orig_rb_thread_stop_timer(); })
+#elif defined(HAVE_SETITIMER)
+#define rb_thread_start_timer() \
+ ({ if (!thread_init || !rb_thread_alone()) orig_rb_thread_start_timer(); })
+#define rb_thread_stop_timer() \
+ ({ if (thread_init) orig_rb_thread_stop_timer(); })
+#endif
+#define rb_thread_atfork() \
+ ({ if (!rb_thread_alone()) orig_rb_thread_atfork(); })
+#else
+void rb_clear_cache _((void));
+void rb_clear_cache_by_class _((VALUE));
+void rb_thread_wait_fd _((int));
+int rb_thread_fd_writable _((int));
+void rb_thread_start_timer _((void));
+void rb_thread_stop_timer _((void));
+void rb_thread_atfork _((void));
+#endif
+
+#ifdef OPT_VARIABLE
+#include "st.h"
+RUBY_EXTERN int special_generic_ivar;
+RUBY_EXTERN st_table *generic_iv_tbl;
+RUBY_EXTERN st_table *rb_global_tbl;
+struct st_table* orig_rb_generic_ivar_table _((VALUE));
+void orig_rb_mark_generic_ivar _((VALUE));
+void orig_rb_mark_generic_ivar_tbl _((void));
+void orig_rb_free_generic_ivar _((VALUE));
+void orig_rb_copy_generic_ivar _((VALUE,VALUE));
+VALUE orig_rb_const_list _((void*));
+void orig_rb_gc_mark_global_tbl _((void));
+#define rb_generic_ivar_table(obj) \
+ ({ VALUE _obj = (obj); \
+ !FL_TEST(_obj, FL_EXIVAR) || !generic_iv_tbl ? 0 : orig_rb_generic_ivar_table(_obj); })
+#define rb_mark_generic_ivar(obj) \
+ ({ VALUE _obj = (obj); \
+ if (generic_iv_tbl) orig_rb_mark_generic_ivar(_obj); })
+#define rb_mark_generic_ivar_tbl() \
+ (((!generic_iv_tbl) || (special_generic_ivar == 0)) ? NULL : orig_rb_mark_generic_ivar_tbl())
+#define rb_free_generic_ivar(obj) \
+ ({ VALUE _obj = (obj); \
+ if (generic_iv_tbl) orig_rb_free_generic_ivar(_obj); })
+#define rb_copy_generic_ivar(clone, obj) \
+ ({ VALUE _obj = (obj); \
+ VALUE _clone = (clone); \
+ if (generic_iv_tbl || FL_TEST(_obj, FL_EXIVAR)) orig_rb_copy_generic_ivar(_clone, _obj); })
+#define rb_const_list(data) \
+ ({ void* _data = (data); \
+ !_data ? rb_ary_new2(0) : orig_rb_const_list(_data); })
+#define rb_gc_mark_global_tbl() \
+ ({if (rb_global_tbl) orig_rb_gc_mark_global_tbl(); })
+#else
+struct st_table* rb_generic_ivar_table _((VALUE));
+void rb_mark_generic_ivar _((VALUE));
+void rb_mark_generic_ivar_tbl _((void));
+void rb_free_generic_ivar _((VALUE));
+void rb_copy_generic_ivar _((VALUE,VALUE));
+VALUE rb_const_list _((void*));
+void rb_gc_mark_global_tbl _((void));
+#endif
+
+#ifdef OPT_NUMERIC
+VALUE orig_rb_num2fix _((VALUE));
+unsigned long orig_rb_fix2uint _((VALUE));
+#define rb_num2ulong(val) \
+ ({ VALUE _val = (val); \
+ TYPE(_val) == T_BIGNUM ? rb_big2ulong(_val) : (unsigned long)rb_num2long(_val); })
+#define rb_num2fix(val) \
+ ({ VALUE _val = (val); \
+ FIXNUM_P(_val) ? _val : orig_rb_num2fix(_val); })
+#if SIZEOF_INT >= SIZEOF_LONG
+#define rb_num2int(val) \
+ rb_num2long(val)
+#define rb_fix2int(val) \
+ FIX2INT(val)
+#else
+#define rb_fix2uint(val) \
+ ({ VALUE _val = (val); \
+ !FIXNUM_P(_val) ? rb_num2uint(_val) : orig_rb_fix2uint(_val); })
+#endif
+#else
+VALUE rb_num2fix _((VALUE));
+unsigned long rb_fix2uint _((VALUE));
+#endif
+
+#endif
\ No newline at end of file
diff --git a/re.c b/re.c
index f2ac99f..2d46a31 100644
--- a/re.c
+++ b/re.c
@@ -108,7 +108,9 @@ rb_memsearch(x0, m, y0, n)
#define KR_REHASH(a, b, h) (((h) << 1) - (((unsigned long)(a))<<d) + (b))
+#ifndef OPT_REXP
if (m > n) return -1;
+#endif
s = y; e = s + n - m;
/* Preprocessing */
@@ -152,6 +154,13 @@ rb_memsearch(x0, m, y0, n)
return s-y;
}
+#ifdef OPT_REXP
+#define rb_memsearch(x0, m, y0, n) \
+ ({ const void* _x0 = (_x0), _y0 = (_y0); \
+ long _m = (m), _n = (n); \
+ _m > _n ? -1 : rb_memsearch(_x0, _m, _y0, _n); })
+#endif
+
#define REG_LITERAL FL_USER5
#define REG_CASESTATE FL_USER0
#define KCODE_NONE 0
@@ -695,8 +704,9 @@ static VALUE
match_init_copy(obj, orig)
VALUE obj, orig;
{
+#ifndef OPT_REXP
if (obj == orig) return obj;
-
+#endif
if (!rb_obj_is_instance_of(orig, rb_obj_class(obj))) {
rb_raise(rb_eTypeError, "wrong argument class");
}
@@ -708,6 +718,11 @@ match_init_copy(obj, orig)
return obj;
}
+#ifdef OPT_REXP
+#define match_init_copy(obj, orig) \
+ ({ VALUE _obj = (obj), _orig = (orig); \
+ _obj == _orig ? _obj : match_init_copy(_obj, _orig); })
+#endif
/*
* call-seq:
@@ -966,11 +981,17 @@ rb_reg_search(re, str, pos, reverse)
}
VALUE
+#ifdef rb_reg_nth_defined
+orig_rb_reg_nth_defined(nth, match)
+#else
rb_reg_nth_defined(nth, match)
+#endif
int nth;
VALUE match;
{
+#ifndef OPT_REXP
if (NIL_P(match)) return Qnil;
+#endif
match_check(match);
if (nth >= RMATCH(match)->regs->num_regs) {
return Qnil;
@@ -984,14 +1005,20 @@ rb_reg_nth_defined(nth, match)
}
VALUE
+#ifdef rb_reg_nth_match
+orig_rb_reg_nth_match(nth, match)
+#else
rb_reg_nth_match(nth, match)
+#endif
int nth;
VALUE match;
{
VALUE str;
long start, end, len;
+#ifndef OPT_REXP
if (NIL_P(match)) return Qnil;
+#endif
match_check(match);
if (nth >= RMATCH(match)->regs->num_regs) {
return Qnil;
@@ -1546,7 +1573,6 @@ rb_reg_hash(re)
return INT2FIX(hashval);
}
-
/*
* call-seq:
* rxp == other_rxp => true or false
@@ -2083,7 +2109,9 @@ static VALUE
rb_reg_init_copy(copy, re)
VALUE copy, re;
{
+#ifndef OPT_REXP
if (copy == re) return copy;
+#endif
rb_check_frozen(copy);
/* need better argument type check */
if (!rb_obj_is_instance_of(re, rb_obj_class(copy))) {
@@ -2095,6 +2123,12 @@ rb_reg_init_copy(copy, re)
return copy;
}
+#ifdef OPT_REXP
+#define rb_reg_init_copy(copy, re) \
+ ({ VALUE _copy = (copy), _re = (re); \
+ _copy == _re ? _copy : rb_reg_init_copy(_copy, _re); })
+#endif
+
VALUE
rb_reg_regsub(str, src, regs)
VALUE str, src;
diff --git a/regex.c b/regex.c
index b92978f..81c1e26 100644
--- a/regex.c
+++ b/regex.c
@@ -509,7 +509,9 @@ static unsigned int
utf8_firstbyte(c)
unsigned long c;
{
+#ifndef OPT_REXP
if (c < 0x80) return c;
+#endif
if (c <= 0x7ff) return ((c>>6)&0xff)|0xc0;
if (c <= 0xffff) return ((c>>12)&0xff)|0xe0;
if (c <= 0x1fffff) return ((c>>18)&0xff)|0xf0;
@@ -522,6 +524,12 @@ utf8_firstbyte(c)
#endif
}
+#ifdef OPT_REXP
+#define utf8_firstbyte(c) \
+ ({ unsigned long _c = (c); \
+ _c < 0x80 ? _c : utf8_firstbyte(_c); })
+#endif
+
#if 0
static void
print_mbc(c)
@@ -1036,7 +1044,9 @@ calculate_must_string(start, end)
unsigned char *pend = (unsigned char *)end;
char *must = 0;
+#ifndef OPT_REXP
if (start == NULL) return 0;
+#endif
/* Loop over pattern commands. */
while (p < pend) {
@@ -1137,6 +1147,12 @@ calculate_must_string(start, end)
return must;
}
+#ifdef OPT_REXP
+#define calculate_must_string(start, end) \
+ ({ char * _start = (start), _end = (end); \
+ _start == NULL ? 0 : calculate_must_string(_start, _end); })
+#endif
+
static unsigned int
read_backslash(c)
int c;
@@ -4454,12 +4470,18 @@ memcmp_translate(s1, s2, len)
}
void
+#ifdef OPT_REXP
+orig_re_copy_registers(regs1, regs2)
+#else
re_copy_registers(regs1, regs2)
+#endif
struct re_registers *regs1, *regs2;
{
int i;
+#ifndef OPT_REXP
if (regs1 == regs2) return;
+#endif
if (regs1->allocated == 0) {
regs1->beg = TMALLOC(regs2->num_regs, int);
regs1->end = TMALLOC(regs2->num_regs, int);
@@ -4478,10 +4500,16 @@ re_copy_registers(regs1, regs2)
}
void
+#ifdef OPT_REXP
+orig_re_free_registers(regs)
+#else
re_free_registers(regs)
+#endif
struct re_registers *regs;
{
+#ifndef OPT_REXP
if (regs->allocated == 0) return;
+#endif
if (regs->beg) xfree(regs->beg);
if (regs->end) xfree(regs->end);
}
diff --git a/regex.h b/regex.h
index fe4dbbb..0ae7759 100644
--- a/regex.h
+++ b/regex.h
@@ -31,9 +31,11 @@
# define re_adjust_startpos ruby_re_adjust_startpos
# define re_compile_fastmap ruby_re_compile_fastmap
# define re_compile_pattern ruby_re_compile_pattern
+#ifndef OPT_REXP
# define re_copy_registers ruby_re_copy_registers
-# define re_free_pattern ruby_re_free_pattern
# define re_free_registers ruby_re_free_registers
+#endif
+# define re_free_pattern ruby_re_free_pattern
# define re_match ruby_re_match
# define re_mbcinit ruby_re_mbcinit
# define re_search ruby_re_search
@@ -194,8 +196,24 @@ extern int re_search (struct re_pattern_buffer *, const char*, int, int, int,
extern int re_match (struct re_pattern_buffer *, const char *, int, int,
struct re_registers *);
extern void re_set_casetable (const char *table);
+#ifdef OPT_REXP
+extern void orig_re_copy_registers (struct re_registers*, struct re_registers*);
+extern void orig_re_free_registers (struct re_registers*);
+#define re_copy_registers(regs1, regs2) \
+ ({ struct re_registers* _regs1 = (regs1); \
+ struct re_registers* _regs2 = (regs2); \
+ if (_regs1 != _regs2) orig_re_copy_registers(_regs1, _regs2); })
+#define re_free_registers(regs) \
+ ({ struct re_registers* _regs = (regs); \
+ if (_regs->allocated != 0) orig_re_free_registers(_regs); })
+#ifdef RUBY
+# define re_copy_registers ruby_re_copy_registers
+# define re_free_registers ruby_re_free_registers
+#endif
+#else
extern void re_copy_registers (struct re_registers*, struct re_registers*);
extern void re_free_registers (struct re_registers*);
+#endif
#ifndef RUBY
/* 4.2 bsd compatibility. */
@@ -213,8 +231,24 @@ extern void re_compile_fastmap ();
extern int re_search ();
extern int re_match ();
extern void re_set_casetable ();
+#ifdef OPT_REXP
+extern void orig_re_copy_registers ();
+extern void orig_re_free_registers ();
+#define re_copy_registers(regs1, regs2) \
+ ({ struct re_registers* _regs1 = (regs1); \
+ struct re_registers* _regs2 = (regs2); \
+ if (_regs1 != _regs2) orig_re_copy_registers(_regs1, _regs2); })
+#define re_free_registers(regs) \
+ ({ struct re_registers* _regs = (regs); \
+ if (_regs->allocated != 0) orig_re_free_registers(_regs); })
+#ifdef RUBY
+# define re_copy_registers ruby_re_copy_registers
+# define re_free_registers ruby_re_free_registers
+#endif
+#else
extern void re_copy_registers ();
extern void re_free_registers ();
+#endif
#endif /* __STDC__ */
diff --git a/ruby.h b/ruby.h
index 4d003a8..97c99e5 100644
--- a/ruby.h
+++ b/ruby.h
@@ -785,4 +785,5 @@ void ruby_native_thread_kill _((int));
} /* extern "C" { */
#endif
-#endif /* ifndef RUBY_H */
+#include "optimizations.h"
+#endif /* ifndef RUBY_H */
\ No newline at end of file
diff --git a/st.c b/st.c
index c16c310..920a54a 100644
--- a/st.c
+++ b/st.c
@@ -452,6 +452,7 @@ st_delete_safe(table, key, value, never)
return 0;
}
+#ifndef OPT_ST
static int
delete_never(key, value, never)
st_data_t key, value, never;
@@ -459,6 +460,11 @@ delete_never(key, value, never)
if (value == never) return ST_DELETE;
return ST_CONTINUE;
}
+#else
+#define delete_never(key, value, never) \
+ ({ st_data_t _key = (key), _value = (value), _never = (never);
+ _value == _never ? ST_DELETE : ST_CONTINUE; })
+#endif
void
st_cleanup_safe(table, never)
diff --git a/string.c b/string.c
index 69430c6..dfa5bb2 100644
--- a/string.c
+++ b/string.c
@@ -181,12 +181,18 @@ str_new4(klass, str)
}
VALUE
+#ifdef rb_str_new4
+orig_rb_str_new4(orig)
+#else
rb_str_new4(orig)
+#endif
VALUE orig;
{
VALUE klass, str;
+#ifndef OPT_STRING
if (OBJ_FROZEN(orig)) return orig;
+#endif
klass = rb_obj_class(orig);
if (FL_TEST(orig, ELTS_SHARED) && (str = RSTRING(orig)->aux.shared) && klass == RBASIC(str)->klass) {
long ofs;
@@ -268,7 +274,11 @@ static void
rb_str_shared_replace(str, str2)
VALUE str, str2;
{
+
+#ifndef OPT_STRING
if (str == str2) return;
+#endif
+
rb_str_modify(str);
if (!FL_TEST(str, ELTS_SHARED)) free(RSTRING(str)->ptr);
if (NIL_P(str2)) {
@@ -295,17 +305,29 @@ rb_str_shared_replace(str, str2)
if (OBJ_TAINTED(str2)) OBJ_TAINT(str);
}
+#ifdef OPT_STRING
+#define rb_str_shared_replace(str, str2) \
+ ({ VALUE _str = (str), _str2 = (str2); \
+ if (_str != _str2) rb_str_shared_replace(_str, _str2); })
+#endif
+
static ID id_to_s;
VALUE
+#ifdef rb_obj_as_string
+orig_rb_obj_as_string(obj)
+#else
rb_obj_as_string(obj)
+#endif
VALUE obj;
{
VALUE str;
+#ifndef OPT_STRING
if (TYPE(obj) == T_STRING) {
return obj;
}
+#endif
str = rb_funcall(obj, id_to_s, 0);
if (TYPE(str) != T_STRING)
return rb_any_to_s(obj);
@@ -473,7 +495,11 @@ rb_str_format_m(str, arg)
static const char null_str[] = "";
+#ifdef OPT_STRING
+int
+#else
static int
+#endif
str_independent(str)
VALUE str;
{
@@ -488,7 +514,11 @@ str_independent(str)
return 0;
}
+#ifdef OPT_STRING
+void
+#else
static void
+#endif
str_make_independent(str)
VALUE str;
{
@@ -504,6 +534,7 @@ str_make_independent(str)
FL_UNSET(str, STR_NOCAPA);
}
+#ifndef rb_str_modify
void
rb_str_modify(str)
VALUE str;
@@ -511,16 +542,23 @@ rb_str_modify(str)
if (!str_independent(str))
str_make_independent(str);
}
+#endif
void
+#ifdef rb_str_associate
+orig_rb_str_associate(str, add)
+#else
rb_str_associate(str, add)
+#endif
VALUE str, add;
{
+#ifndef OPT_STRING
if (FL_TEST(str, STR_ASSOC)) {
/* already associated */
rb_ary_concat(RSTRING(str)->aux.shared, add);
}
else {
+#endif
if (FL_TEST(str, ELTS_SHARED)) {
str_make_independent(str);
}
@@ -529,16 +567,24 @@ rb_str_associate(str, add)
}
RSTRING(str)->aux.shared = add;
FL_SET(str, STR_ASSOC);
+#ifndef OPT_STRING
}
+#endif
}
VALUE
+#ifdef rb_str_associated
+orig_rb_str_associated(str)
+#else
rb_str_associated(str)
+#endif
VALUE str;
{
+#ifndef OPT_STRING
if (FL_TEST(str, STR_ASSOC)) {
return RSTRING(str)->aux.shared;
}
+#endif
return Qfalse;
}
@@ -604,14 +650,20 @@ rb_check_string_type(str)
}
VALUE
+#ifdef rb_str_substr
+orig_rb_str_substr(str, beg, len)
+#else
rb_str_substr(str, beg, len)
+#endif
VALUE str;
long beg, len;
{
VALUE str2;
+#ifndef OPT_STRING
if (len < 0) return Qnil;
if (beg > RSTRING(str)->len) return Qnil;
+#endif
if (beg < 0) {
beg += RSTRING(str)->len;
if (beg < 0) return Qnil;
@@ -761,12 +813,18 @@ str_buf_cat(str, ptr, len)
}
VALUE
+#ifdef rb_str_buf_cat
+orig_rb_str_buf_cat(str, ptr, len)
+#else
rb_str_buf_cat(str, ptr, len)
+#endif
VALUE str;
const char *ptr;
long len;
{
+#ifndef OPT_STRING
if (len == 0) return str;
+#endif
if (len < 0) {
rb_raise(rb_eArgError, "negative string size (or size too big)");
}
@@ -989,7 +1047,6 @@ rb_str_eql(str1, str2)
{
if (TYPE(str2) != T_STRING || RSTRING(str1)->len != RSTRING(str2)->len)
return Qfalse;
-
if (memcmp(RSTRING(str1)->ptr, RSTRING(str2)->ptr,
lesser(RSTRING(str1)->len, RSTRING(str2)->len)) == 0)
return Qtrue;
@@ -2501,7 +2558,6 @@ rb_str_reverse(str)
return obj;
}
-
/*
* call-seq:
* str.include? other_str => true or false
diff --git a/struct.c b/struct.c
index 9417c1c..db2a361 100644
--- a/struct.c
+++ b/struct.c
@@ -552,7 +552,9 @@ static VALUE
rb_struct_init_copy(copy, s)
VALUE copy, s;
{
+#ifndef OPT_STRUCT
if (copy == s) return copy;
+#endif
rb_check_frozen(copy);
if (!rb_obj_is_instance_of(s, rb_obj_class(copy))) {
rb_raise(rb_eTypeError, "wrong argument class");
@@ -565,6 +567,12 @@ rb_struct_init_copy(copy, s)
return copy;
}
+#ifdef OPT_STRUCT
+#define rb_struct_init_copy(copy, s) \
+ ({ VALUE _copy = (copy), _s = (s); \
+ _copy == _s ? _copy : rb_struct_init_copy(_copy, _s); })
+#endif
+
static VALUE
rb_struct_aref_id(s, id)
VALUE s;
diff --git a/time.c b/time.c
index 5cd1c9e..5eda91a 100644
--- a/time.c
+++ b/time.c
@@ -1060,7 +1060,9 @@ time_init_copy(copy, time)
{
struct time_object *tobj, *tcopy;
+#ifndef OPT_TIME
if (copy == time) return copy;
+#endif
time_modify(copy);
if (TYPE(time) != T_DATA || RDATA(time)->dfree != time_free) {
rb_raise(rb_eTypeError, "wrong argument type");
@@ -1072,6 +1074,12 @@ time_init_copy(copy, time)
return copy;
}
+#ifdef OPT_TIME
+#define time_init_copy(copy, time) \
+ ({ VALUE _copy = (copy), _time = (time); \
+ _copy == _time ? _copy : time_init_copy(_copy, _time); })
+#endif
+
static VALUE
time_dup(time)
VALUE time;
@@ -1212,10 +1220,19 @@ time_get_tm(time, gmt)
VALUE time;
int gmt;
{
+#ifndef OPT_TIME
if (gmt) return time_gmtime(time);
+#endif
return time_localtime(time);
}
+#ifdef OPT_TIME
+#define time_get_tm(time, gmt) \
+ ({ VALUE _time = (time); \
+ int _gmt = (gmt); \
+ _gmt ? time_gmtime(_time) : time_get_tm(_time, _gmt); })
+#endif
+
/*
* call-seq:
* time.asctime => string
diff --git a/util.c b/util.c
index 961aaba..b8ab3e7 100644
--- a/util.c
+++ b/util.c
@@ -414,7 +414,9 @@ static void mmswap_(a, b, mmarg)
int mmarg;
{
register int s;
+#ifndef OPT_UTIL
if (a == b) return;
+#endif
if (mmkind >= 0) {
if (mmkind > 0) {
register char *t = a + high;
@@ -434,6 +436,12 @@ static void mmswap_(a, b, mmarg)
do {s = *a; *a++ = *b; *b++ = s;} while (a < t);
}
}
+
+#ifdef OPT_UTIL
+#define mmswap_(a, b, mmarg) \
+ ({ if (a != b) mmswap_(a, b, mmarg); })
+#endif
+
#define mmswap(a,b) mmswap_((a),(b),mmarg)
static void mmrot3_(a, b, c, mmarg)
@@ -479,7 +487,11 @@ typedef struct { char *LL, *RR; } stack_node; /* Stack structure for L,l,R,r */
((*cmp)(b,c,d)<0 ? b : ((*cmp)(a,c,d)<0 ? c : a)) : \
((*cmp)(b,c,d)>0 ? b : ((*cmp)(a,c,d)<0 ? a : c)))
+#ifdef ruby_qsort
+void orig_ruby_qsort (base, nel, size, cmp, d)
+#else
void ruby_qsort (base, nel, size, cmp, d)
+#endif
void* base;
const int nel;
const int size;
diff --git a/util.h b/util.h
index b00c096..8fc015a 100644
--- a/util.h
+++ b/util.h
@@ -43,7 +43,14 @@ unsigned long scan_hex _((const char*, int, int*));
void ruby_add_suffix();
#endif
-void ruby_qsort _((void*, const int, const int, int (*)(), void*));
+#ifdef OPT_UTIL
+void orig_ruby_qsort _((void*, const int, const int, int (*)(), void*));
+#define ruby_qsort(base, nel, size, cmp, d) \
+ ({ const int _nel = (nel); \
+ if (_nel >= 1) orig_ruby_qsort(base, _nel, size, cmp, d); })
+#else
+ void ruby_qsort _((void*, const int, const int, int (*)(), void*));
+#endif
#define qsort(b,n,s,c,d) ruby_qsort(b,n,s,c,d)
void ruby_setenv _((const char*, const char*));
diff --git a/variable.c b/variable.c
index 53143ca..667b6ff 100644
--- a/variable.c
+++ b/variable.c
@@ -73,8 +73,9 @@ fc_i(key, value, res)
VALUE value;
struct fc_result *res;
{
+#ifndef OPT_VARIABLE
if (!rb_is_const_id(key)) return ST_CONTINUE;
-
+#endif
if (value == res->klass) {
res->path = fc_path(res, key);
return ST_STOP;
@@ -112,6 +113,14 @@ fc_i(key, value, res)
return ST_CONTINUE;
}
+#ifdef OPT_VARIABLE
+#define fc_i(key,value,res) \
+ ({ ID _key = (key); \
+ VALUE _value = (value); \
+ struct fc_result * _res = (res); \
+ !rb_is_const_id(_key) ? ST_CONTINUE : fc_i(_key,_value,_res); });
+#endif
+
static VALUE
find_class_path(klass)
VALUE klass;
@@ -429,10 +438,19 @@ var_getter(id, var)
ID id;
VALUE *var;
{
+#ifndef OPT_VARIABLE
if (!var) return Qnil;
+#endif
return *var;
}
+#ifdef OPT_VARIABLE
+#define var_getter(id, var) \
+ ({ ID _id = (id); \
+ VALUE * _var = (var); \
+ !_var ? Qnil : var_getter(_id, _var); })
+#endif
+
static void
var_setter(val, id, var)
VALUE val;
@@ -476,11 +494,19 @@ mark_global_entry(key, entry)
}
void
+#ifdef OPT_VARIABLE
+orig_rb_gc_mark_global_tbl()
+#else
rb_gc_mark_global_tbl()
+#endif
{
+#ifndef OPT_VARIABLE
if (rb_global_tbl) {
+#endif
st_foreach(rb_global_tbl, mark_global_entry, 0);
+#ifndef OPT_VARIABLE
}
+#endif
}
static ID
@@ -842,17 +868,28 @@ rb_alias_variable(name1, name2)
entry1->var = entry2->var;
}
+#ifdef OPT_VARIABLE
+int special_generic_ivar = 0;
+st_table *generic_iv_tbl;
+#else
static int special_generic_ivar = 0;
static st_table *generic_iv_tbl;
+#endif
st_table*
+#ifdef rb_generic_ivar_table
+orig_rb_generic_ivar_table(obj)
+#else
rb_generic_ivar_table(obj)
+#endif
VALUE obj;
{
st_data_t tbl;
+#ifndef OPT_VARIABLE
if (!FL_TEST(obj, FL_EXIVAR)) return 0;
if (!generic_iv_tbl) return 0;
+#endif
if (!st_lookup(generic_iv_tbl, obj, &tbl)) return 0;
return (st_table *)tbl;
}
@@ -914,7 +951,9 @@ generic_ivar_defined(obj, id)
st_data_t data;
VALUE val;
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return Qfalse;
+#endif
if (!st_lookup(generic_iv_tbl, obj, &data)) return Qfalse;
tbl = (st_table *)data;
if (st_lookup(tbl, id, &val)) {
@@ -923,6 +962,13 @@ generic_ivar_defined(obj, id)
return Qfalse;
}
+#ifdef OPT_VARIABLE
+#define generic_ivar_defined(obj, id) \
+ ({ ID _id = (id); \
+ VALUE _obj = (obj); \
+ !generic_iv_tbl ? Qfalse : generic_ivar_defined(_obj, _id); })
+#endif
+
static int
generic_ivar_remove(obj, id, valp)
VALUE obj;
@@ -933,7 +979,9 @@ generic_ivar_remove(obj, id, valp)
st_data_t data;
int status;
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return 0;
+#endif
if (!st_lookup(generic_iv_tbl, obj, &data)) return 0;
tbl = (st_table *)data;
status = st_delete(tbl, &id, valp);
@@ -944,13 +992,27 @@ generic_ivar_remove(obj, id, valp)
return status;
}
+#ifdef OPT_VARIABLE
+#define generic_ivar_remove(obj, id, valp) \
+ ({ ID _id = (id); \
+ VALUE _obj = (obj); \
+ VALUE * _valp = (valp); \
+ !generic_iv_tbl ? 0 : generic_ivar_remove(_obj, _id, _valp); })
+#endif
+
void
+#ifdef rb_mark_generic_ivar
+orig_rb_mark_generic_ivar(obj)
+#else
rb_mark_generic_ivar(obj)
+#endif
VALUE obj;
{
st_data_t tbl;
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return;
+#endif
if (st_lookup(generic_iv_tbl, obj, &tbl)) {
rb_mark_tbl((st_table *)tbl);
}
@@ -977,32 +1039,50 @@ givar_i(obj, tbl)
}
void
+#ifdef rb_mark_generic_ivar_tbl
+orig_rb_mark_generic_ivar_tbl()
+#else
rb_mark_generic_ivar_tbl()
+#endif
{
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return;
if (special_generic_ivar == 0) return;
+#endif
st_foreach_safe(generic_iv_tbl, givar_i, 0);
}
void
+#ifdef rb_free_generic_ivar
+orig_rb_free_generic_ivar(obj)
+#else
rb_free_generic_ivar(obj)
+#endif
VALUE obj;
{
st_data_t tbl;
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return;
+#endif
if (st_delete(generic_iv_tbl, &obj, &tbl))
st_free_table((st_table *)tbl);
}
void
+#ifdef rb_copy_generic_ivar
+orig_rb_copy_generic_ivar(clone, obj)
+#else
rb_copy_generic_ivar(clone, obj)
+#endif
VALUE clone, obj;
{
st_data_t data;
+#ifndef OPT_VARIABLE
if (!generic_iv_tbl) return;
if (!FL_TEST(obj, FL_EXIVAR)) return;
+#endif
if (st_lookup(generic_iv_tbl, obj, &data)) {
st_table *tbl = (st_table *)data;
@@ -1281,7 +1361,11 @@ check_autoload_table(av)
VALUE av;
{
Check_Type(av, T_DATA);
+#ifndef OPT_GC
if (RDATA(av)->dmark != (RUBY_DATA_FUNC)rb_mark_tbl ||
+#else
+ if (RDATA(av)->dmark != (RUBY_DATA_FUNC)orig_rb_mark_tbl ||
+#endif
RDATA(av)->dfree != (RUBY_DATA_FUNC)st_free_table) {
rb_raise(rb_eTypeError, "wrong autoload table: %s", RSTRING(rb_inspect(av))->ptr);
}
@@ -1313,7 +1397,11 @@ rb_autoload(mod, id, file)
tbl = check_autoload_table(av);
}
else {
+#ifndef OPT_GC
av = Data_Wrap_Struct(0 , rb_mark_tbl, st_free_table, 0);
+#else
+ av = Data_Wrap_Struct(0 , orig_rb_mark_tbl, st_free_table, 0);
+#endif
st_add_direct(tbl, autoload, av);
DATA_PTR(av) = tbl = st_init_numtable();
}
@@ -1557,13 +1645,19 @@ list_i(key, value, ary)
}
VALUE
+#ifdef rb_const_list
+orig_rb_const_list(data)
+#else
rb_const_list(data)
+#endif
void *data;
{
st_table *tbl = data;
VALUE ary;
+#ifndef OPT_VARIABLE
if (!tbl) return rb_ary_new2(0);
+#endif
ary = rb_ary_new2(tbl->num_entries);
st_foreach(tbl, list_i, ary);
st_free_table(tbl);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment