llrb 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (98) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +21 -0
  3. data/.gitmodules +4 -0
  4. data/.rspec +2 -0
  5. data/.travis.yml +5 -0
  6. data/Gemfile +4 -0
  7. data/LICENSE.txt +56 -0
  8. data/README.md +311 -0
  9. data/Rakefile +30 -0
  10. data/bin/bm_app_fib +41 -0
  11. data/bin/bm_empty_method +33 -0
  12. data/bin/bm_loop_while +27 -0
  13. data/bin/bm_plus +33 -0
  14. data/bin/console +14 -0
  15. data/bin/loop_while.rb +5 -0
  16. data/bin/setup +8 -0
  17. data/ext/llrb/cfg.h +124 -0
  18. data/ext/llrb/compiler.c +987 -0
  19. data/ext/llrb/compiler/funcs.h +164 -0
  20. data/ext/llrb/compiler/stack.h +43 -0
  21. data/ext/llrb/cruby.h +42 -0
  22. data/ext/llrb/cruby/ccan/build_assert/build_assert.h +40 -0
  23. data/ext/llrb/cruby/ccan/check_type/check_type.h +63 -0
  24. data/ext/llrb/cruby/ccan/container_of/container_of.h +142 -0
  25. data/ext/llrb/cruby/ccan/list/list.h +773 -0
  26. data/ext/llrb/cruby/ccan/str/str.h +16 -0
  27. data/ext/llrb/cruby/internal.h +1774 -0
  28. data/ext/llrb/cruby/iseq.h +252 -0
  29. data/ext/llrb/cruby/method.h +213 -0
  30. data/ext/llrb/cruby/node.h +520 -0
  31. data/ext/llrb/cruby/probes_helper.h +43 -0
  32. data/ext/llrb/cruby/ruby_assert.h +54 -0
  33. data/ext/llrb/cruby/ruby_atomic.h +233 -0
  34. data/ext/llrb/cruby/thread_pthread.h +54 -0
  35. data/ext/llrb/cruby/vm_core.h +1646 -0
  36. data/ext/llrb/cruby/vm_debug.h +37 -0
  37. data/ext/llrb/cruby/vm_exec.h +182 -0
  38. data/ext/llrb/cruby/vm_opts.h +57 -0
  39. data/ext/llrb/cruby_extra/id.h +220 -0
  40. data/ext/llrb/cruby_extra/insns.inc +113 -0
  41. data/ext/llrb/cruby_extra/insns_info.inc +796 -0
  42. data/ext/llrb/cruby_extra/probes.h +80 -0
  43. data/ext/llrb/extconf.rb +102 -0
  44. data/ext/llrb/llrb.c +148 -0
  45. data/ext/llrb/optimizer.cc +118 -0
  46. data/ext/llrb/parser.c +191 -0
  47. data/ext/llrb/profiler.c +336 -0
  48. data/ext/llrb_insn_checkkeyword.c +20 -0
  49. data/ext/llrb_insn_checkmatch.c +28 -0
  50. data/ext/llrb_insn_concatarray.c +23 -0
  51. data/ext/llrb_insn_concatstrings.c +21 -0
  52. data/ext/llrb_insn_defined.c +9 -0
  53. data/ext/llrb_insn_getclassvariable.c +10 -0
  54. data/ext/llrb_insn_getinstancevariable.c +44 -0
  55. data/ext/llrb_insn_getlocal.c +14 -0
  56. data/ext/llrb_insn_getlocal_level0.c +8 -0
  57. data/ext/llrb_insn_getlocal_level1.c +8 -0
  58. data/ext/llrb_insn_getspecial.c +14 -0
  59. data/ext/llrb_insn_invokeblock.c +39 -0
  60. data/ext/llrb_insn_invokesuper.c +47 -0
  61. data/ext/llrb_insn_opt_aref.c +25 -0
  62. data/ext/llrb_insn_opt_aset.c +28 -0
  63. data/ext/llrb_insn_opt_div.c +32 -0
  64. data/ext/llrb_insn_opt_eq.c +57 -0
  65. data/ext/llrb_insn_opt_ge.c +28 -0
  66. data/ext/llrb_insn_opt_gt.c +38 -0
  67. data/ext/llrb_insn_opt_le.c +29 -0
  68. data/ext/llrb_insn_opt_lt.c +38 -0
  69. data/ext/llrb_insn_opt_ltlt.c +27 -0
  70. data/ext/llrb_insn_opt_minus.c +36 -0
  71. data/ext/llrb_insn_opt_mod.c +32 -0
  72. data/ext/llrb_insn_opt_mult.c +30 -0
  73. data/ext/llrb_insn_opt_neq.c +103 -0
  74. data/ext/llrb_insn_opt_plus.c +48 -0
  75. data/ext/llrb_insn_opt_send_without_block.c +45 -0
  76. data/ext/llrb_insn_opt_str_freeze.c +12 -0
  77. data/ext/llrb_insn_putspecialobject.c +23 -0
  78. data/ext/llrb_insn_send.c +49 -0
  79. data/ext/llrb_insn_setclassvariable.c +19 -0
  80. data/ext/llrb_insn_setconstant.c +23 -0
  81. data/ext/llrb_insn_setinstancevariable.c +48 -0
  82. data/ext/llrb_insn_setlocal.c +16 -0
  83. data/ext/llrb_insn_setlocal_level0.c +9 -0
  84. data/ext/llrb_insn_setlocal_level1.c +10 -0
  85. data/ext/llrb_insn_setspecial.c +15 -0
  86. data/ext/llrb_insn_splatarray.c +13 -0
  87. data/ext/llrb_insn_throw.c +11 -0
  88. data/ext/llrb_insn_trace.c +37 -0
  89. data/ext/llrb_push_result.c +14 -0
  90. data/ext/llrb_self_from_cfp.c +12 -0
  91. data/ext/llrb_set_pc.c +8 -0
  92. data/lib/llrb.rb +2 -0
  93. data/lib/llrb/jit.rb +76 -0
  94. data/lib/llrb/start.rb +2 -0
  95. data/lib/llrb/version.rb +3 -0
  96. data/llrb.gemspec +48 -0
  97. data/wercker.yml +31 -0
  98. metadata +227 -0
@@ -0,0 +1,20 @@
1
+ #include "cruby.h"
2
+
3
+ // TODO: Use vm_check_keyword after Ruby 2.5
4
+ VALUE
5
+ llrb_insn_checkkeyword(VALUE cfp_v, lindex_t kw_bits_index, rb_num_t keyword_index)
6
+ {
7
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
8
+
9
+ const VALUE *ep = cfp->ep;
10
+ const VALUE kw_bits = *(ep - kw_bits_index);
11
+
12
+ if (FIXNUM_P(kw_bits)) {
13
+ int bits = FIX2INT(kw_bits);
14
+ return (bits & (0x01 << keyword_index)) ? Qfalse : Qtrue;
15
+ }
16
+ else {
17
+ VM_ASSERT(RB_TYPE_P(kw_bits, T_HASH));
18
+ return rb_hash_has_key(kw_bits, INT2FIX(keyword_index)) ? Qfalse : Qtrue;
19
+ }
20
+ }
@@ -0,0 +1,28 @@
1
+ #include "cruby.h"
2
+
3
+ // NOTE: There's optimization chance to check flag beforehand.
4
+ // TODO: Use `vm_check_match` after Ruby 2.5.
5
+ VALUE check_match(VALUE pattern, VALUE target, enum vm_check_match_type type);
6
+ VALUE
7
+ llrb_insn_checkmatch(VALUE target, VALUE pattern, rb_num_t flag)
8
+ {
9
+ enum vm_check_match_type checkmatch_type =
10
+ (enum vm_check_match_type)(flag & VM_CHECKMATCH_TYPE_MASK);
11
+ VALUE result = Qfalse;
12
+
13
+ if (flag & VM_CHECKMATCH_ARRAY) {
14
+ long i;
15
+ for (i = 0; i < RARRAY_LEN(pattern); i++) {
16
+ if (RTEST(check_match(RARRAY_AREF(pattern, i), target, checkmatch_type))) {
17
+ result = Qtrue;
18
+ break;
19
+ }
20
+ }
21
+ }
22
+ else {
23
+ if (RTEST(check_match(pattern, target, checkmatch_type))) {
24
+ result = Qtrue;
25
+ }
26
+ }
27
+ return result;
28
+ }
@@ -0,0 +1,23 @@
1
+ #include "cruby.h"
2
+
3
+ // TODO: Use vm_concat_array after Ruby 2.5
4
+ VALUE
5
+ llrb_insn_concatarray(VALUE ary1, VALUE ary2st)
6
+ {
7
+ const VALUE ary2 = ary2st;
8
+ VALUE tmp1 = rb_check_convert_type(ary1, T_ARRAY, "Array", "to_a");
9
+ VALUE tmp2 = rb_check_convert_type(ary2, T_ARRAY, "Array", "to_a");
10
+
11
+ if (NIL_P(tmp1)) {
12
+ tmp1 = rb_ary_new3(1, ary1);
13
+ }
14
+
15
+ if (NIL_P(tmp2)) {
16
+ tmp2 = rb_ary_new3(1, ary2);
17
+ }
18
+
19
+ if (tmp1 == ary1) {
20
+ tmp1 = rb_ary_dup(ary1);
21
+ }
22
+ return rb_ary_concat(tmp1, tmp2);
23
+ }
@@ -0,0 +1,21 @@
1
+ #include <stdarg.h>
2
+ #include "cruby.h"
3
+
4
+ // https://github.com/ruby/ruby/blob/v2_4_1/insns.def#L359-L372
5
+ extern VALUE rb_str_concat_literals(size_t, const VALUE*);
6
+ VALUE
7
+ llrb_insn_concatstrings(size_t num, ...) {
8
+ VALUE *args = 0;
9
+ va_list ar;
10
+
11
+ if (num > 0) {
12
+ args = ALLOCA_N(VALUE, num);
13
+ va_start(ar, num);
14
+ for (size_t i = 0; i < num; i++) {
15
+ args[i] = va_arg(ar, VALUE);
16
+ }
17
+ va_end(ar);
18
+ }
19
+
20
+ return rb_str_concat_literals(num, args);
21
+ }
@@ -0,0 +1,9 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_defined(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t op_type, VALUE obj, VALUE needstr, VALUE v);
4
+ VALUE
5
+ llrb_insn_defined(rb_num_t op_type, VALUE obj, VALUE needstr, VALUE v)
6
+ {
7
+ rb_thread_t *th = GET_THREAD();
8
+ return vm_defined(th, th->cfp, op_type, obj, needstr, v);
9
+ }
@@ -0,0 +1,10 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_get_cvar_base(const rb_cref_t *cref, rb_control_frame_t *cfp);
4
+ rb_cref_t * rb_vm_get_cref(const VALUE *ep);
5
+ VALUE
6
+ llrb_insn_getclassvariable(VALUE cfp_v, ID id)
7
+ {
8
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
9
+ return rb_cvar_get(vm_get_cvar_base(rb_vm_get_cref(cfp->ep), cfp), id);
10
+ }
@@ -0,0 +1,44 @@
1
+ #include "cruby.h"
2
+
3
+ static inline VALUE
4
+ vm_getivar(VALUE obj, ID id, IC ic)
5
+ {
6
+ if (LIKELY(RB_TYPE_P(obj, T_OBJECT))) {
7
+ VALUE val = Qundef;
8
+ if (LIKELY(ic->ic_serial == RCLASS_SERIAL(RBASIC(obj)->klass))) {
9
+ st_index_t index = ic->ic_value.index;
10
+ if (LIKELY(index < ROBJECT_NUMIV(obj))) {
11
+ val = ROBJECT_IVPTR(obj)[index];
12
+ }
13
+ undef_check:
14
+ if (UNLIKELY(val == Qundef)) {
15
+ if (RTEST(ruby_verbose))
16
+ rb_warning("instance variable %"PRIsVALUE" not initialized", QUOTE_ID(id));
17
+ val = Qnil;
18
+ }
19
+ return val;
20
+ }
21
+ else {
22
+ st_data_t index;
23
+ struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
24
+
25
+ if (iv_index_tbl) {
26
+ if (st_lookup(iv_index_tbl, id, &index)) {
27
+ if (index < ROBJECT_NUMIV(obj)) {
28
+ val = ROBJECT_IVPTR(obj)[index];
29
+ }
30
+ ic->ic_value.index = index;
31
+ ic->ic_serial = RCLASS_SERIAL(RBASIC(obj)->klass);
32
+ }
33
+ }
34
+ goto undef_check;
35
+ }
36
+ }
37
+ return rb_ivar_get(obj, id);
38
+ }
39
+
40
+ VALUE
41
+ llrb_insn_getinstancevariable(VALUE obj, ID id, VALUE ic_v)
42
+ {
43
+ return vm_getivar(obj, id, (IC)ic_v);
44
+ }
@@ -0,0 +1,14 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_getlocal(VALUE cfp_v, lindex_t idx, rb_num_t level)
5
+ {
6
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
7
+ int i, lev = (int)level;
8
+ const VALUE *ep = cfp->ep;
9
+
10
+ for (i = 0; i < lev; i++) {
11
+ ep = GET_PREV_EP(ep);
12
+ }
13
+ return *(ep - idx);
14
+ }
@@ -0,0 +1,8 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_getlocal_level0(VALUE cfp_v, lindex_t idx)
5
+ {
6
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
7
+ return *(cfp->ep - idx);
8
+ }
@@ -0,0 +1,8 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_getlocal_level1(VALUE cfp_v, lindex_t idx)
5
+ {
6
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
7
+ return *(GET_PREV_EP(cfp->ep) - idx);
8
+ }
@@ -0,0 +1,14 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_getspecial(rb_thread_t *th, const VALUE *lep, rb_num_t key, rb_num_t type);
4
+ VALUE
5
+ llrb_insn_getspecial(rb_num_t key, rb_num_t type)
6
+ {
7
+ rb_thread_t *th = GET_THREAD();
8
+
9
+ const VALUE *ep = th->cfp->ep;
10
+ while (!VM_ENV_LOCAL_P(ep)) {
11
+ ep = VM_ENV_PREV_EP(ep);
12
+ }
13
+ return vm_getspecial(th, ep, key, type);
14
+ }
@@ -0,0 +1,39 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_exec(rb_thread_t *th);
4
+
5
+ static inline void
6
+ _llrb_push_result(rb_control_frame_t *cfp, VALUE result)
7
+ {
8
+ // PUSH(result)
9
+ *(cfp->sp) = result;
10
+ cfp->sp += 1;
11
+ }
12
+
13
+ VALUE vm_invoke_block(rb_thread_t *th, rb_control_frame_t *reg_cfp, struct rb_calling_info *calling, const struct rb_call_info *ci);
14
+ VALUE
15
+ llrb_insn_invokeblock(VALUE th_v, VALUE cfp_v, VALUE ci_v, unsigned int stack_size, ...)
16
+ {
17
+ rb_thread_t *th = (rb_thread_t *)th_v;
18
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
19
+ CALL_INFO ci = (CALL_INFO)ci_v;
20
+
21
+ va_list ar;
22
+ va_start(ar, stack_size);
23
+ for (unsigned int i = 0; i < stack_size; i++) {
24
+ _llrb_push_result(cfp, va_arg(ar, VALUE));
25
+ }
26
+ va_end(ar);
27
+
28
+ struct rb_calling_info calling;
29
+ calling.argc = ci->orig_argc;
30
+ calling.block_handler = VM_BLOCK_HANDLER_NONE;
31
+ calling.recv = cfp->self;
32
+
33
+ VALUE val = vm_invoke_block(th, cfp, &calling, ci);
34
+ if (val == Qundef) {
35
+ VM_ENV_FLAGS_SET(th->cfp->ep, VM_FRAME_FLAG_FINISH);
36
+ return vm_exec(th);
37
+ }
38
+ return val;
39
+ }
@@ -0,0 +1,47 @@
1
+ #include "cruby.h"
2
+
3
+ #define CALL_METHOD(calling, ci, cc) (*(cc)->call)(th, cfp, (calling), (ci), (cc))
4
+ VALUE vm_exec(rb_thread_t *th);
5
+
6
+ static inline void
7
+ _llrb_push_result(rb_control_frame_t *cfp, VALUE result)
8
+ {
9
+ // PUSH(result)
10
+ *(cfp->sp) = result;
11
+ cfp->sp += 1;
12
+ }
13
+
14
+ void vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
15
+ struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super);
16
+ void vm_search_super_method(rb_thread_t *th, rb_control_frame_t *reg_cfp,
17
+ struct rb_calling_info *calling, struct rb_call_info *ci, struct rb_call_cache *cc);
18
+ VALUE
19
+ llrb_insn_invokesuper(VALUE th_v, VALUE cfp_v, VALUE ci_v, VALUE cc_v, VALUE blockiseq_v, unsigned int stack_size, ...)
20
+ {
21
+ rb_thread_t *th = (rb_thread_t *)th_v;
22
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
23
+ CALL_INFO ci = (CALL_INFO)ci_v;
24
+ CALL_CACHE cc = (CALL_CACHE)cc_v;
25
+ ISEQ blockiseq = (ISEQ)blockiseq_v;
26
+
27
+ va_list ar;
28
+ va_start(ar, stack_size);
29
+ for (unsigned int i = 0; i < stack_size; i++) {
30
+ _llrb_push_result(cfp, va_arg(ar, VALUE));
31
+ }
32
+ va_end(ar);
33
+
34
+ struct rb_calling_info calling;
35
+ calling.argc = ci->orig_argc;
36
+
37
+ vm_caller_setup_arg_block(th, cfp, &calling, ci, blockiseq, 1);
38
+ calling.recv = th->cfp->self;
39
+ vm_search_super_method(th, th->cfp, &calling, ci, cc);
40
+
41
+ VALUE result = CALL_METHOD(&calling, ci, cc);
42
+ if (result == Qundef) {
43
+ VM_ENV_FLAGS_SET(th->cfp->ep, VM_FRAME_FLAG_FINISH);
44
+ return vm_exec(th);
45
+ }
46
+ return result;
47
+ }
@@ -0,0 +1,25 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_aref(VALUE recv, VALUE obj)
5
+ {
6
+ if (!SPECIAL_CONST_P(recv)) {
7
+ if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_AREF, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
8
+ return rb_ary_entry(recv, FIX2LONG(obj));
9
+ }
10
+ else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_AREF, HASH_REDEFINED_OP_FLAG)) {
11
+ return rb_hash_aref(recv, obj);
12
+ }
13
+ else {
14
+ //goto INSN_LABEL(normal_dispatch);
15
+ return rb_funcall(recv, rb_intern("[]"), 1, obj);
16
+ }
17
+ }
18
+ else {
19
+ //INSN_LABEL(normal_dispatch):
20
+ //PUSH(recv);
21
+ //PUSH(obj);
22
+ //CALL_SIMPLE_METHOD(recv);
23
+ return rb_funcall(recv, rb_intern("[]"), 1, obj);
24
+ }
25
+ }
@@ -0,0 +1,28 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_aset(VALUE recv, VALUE obj, VALUE set)
5
+ {
6
+ if (!SPECIAL_CONST_P(recv)) {
7
+ if (RBASIC_CLASS(recv) == rb_cArray && BASIC_OP_UNREDEFINED_P(BOP_ASET, ARRAY_REDEFINED_OP_FLAG) && FIXNUM_P(obj)) {
8
+ rb_ary_store(recv, FIX2LONG(obj), set);
9
+ return set;
10
+ }
11
+ else if (RBASIC_CLASS(recv) == rb_cHash && BASIC_OP_UNREDEFINED_P(BOP_ASET, HASH_REDEFINED_OP_FLAG)) {
12
+ rb_hash_aset(recv, obj, set);
13
+ return set;
14
+ }
15
+ else {
16
+ //goto INSN_LABEL(normal_dispatch);
17
+ return rb_funcall(recv, '+', 2, obj, set);
18
+ }
19
+ }
20
+ else {
21
+ //INSN_LABEL(normal_dispatch):
22
+ //PUSH(recv);
23
+ //PUSH(obj);
24
+ //PUSH(set);
25
+ //CALL_SIMPLE_METHOD(recv);
26
+ return rb_funcall(recv, '+', 2, obj, set);
27
+ }
28
+ }
@@ -0,0 +1,32 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_div(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_DIV, INTEGER_REDEFINED_OP_FLAG)) {
8
+ //if (FIX2LONG(obj) == 0) goto INSN_LABEL(normal_dispatch);
9
+ if (FIX2LONG(obj) == 0) return rb_funcall(recv, '/', 1, obj);
10
+ return rb_fix_div_fix(recv, obj);
11
+ }
12
+ else if (FLONUM_2_P(recv, obj) &&
13
+ BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
14
+ return DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
15
+ }
16
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
17
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
18
+ // BASIC_OP_UNREDEFINED_P(BOP_DIV, FLOAT_REDEFINED_OP_FLAG)) {
19
+ // val = DBL2NUM(RFLOAT_VALUE(recv) / RFLOAT_VALUE(obj));
20
+ // }
21
+ // else {
22
+ // goto INSN_LABEL(normal_dispatch);
23
+ // }
24
+ //}
25
+ else {
26
+ //INSN_LABEL(normal_dispatch):
27
+ //PUSH(recv);
28
+ //PUSH(obj);
29
+ //CALL_SIMPLE_METHOD(recv);
30
+ return rb_funcall(recv, '/', 1, obj);
31
+ }
32
+ }
@@ -0,0 +1,57 @@
1
+ #include "cruby.h"
2
+
3
+ static inline VALUE
4
+ opt_eq_func(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_EQ, INTEGER_REDEFINED_OP_FLAG)) {
8
+ return (recv == obj) ? Qtrue : Qfalse;
9
+ }
10
+ else if (FLONUM_2_P(recv, obj) &&
11
+ BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
12
+ return (recv == obj) ? Qtrue : Qfalse;
13
+ }
14
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
15
+ // if (RBASIC_CLASS(recv) == rb_cFloat &&
16
+ // RBASIC_CLASS(obj) == rb_cFloat &&
17
+ // BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
18
+ // double a = RFLOAT_VALUE(recv);
19
+ // double b = RFLOAT_VALUE(obj);
20
+
21
+ // if (isnan(a) || isnan(b)) {
22
+ // return Qfalse;
23
+ // }
24
+ // return (a == b) ? Qtrue : Qfalse;
25
+ // }
26
+ // else if (RBASIC_CLASS(recv) == rb_cString &&
27
+ // RBASIC_CLASS(obj) == rb_cString &&
28
+ // BASIC_OP_UNREDEFINED_P(BOP_EQ, STRING_REDEFINED_OP_FLAG)) {
29
+ // return rb_str_equal(recv, obj);
30
+ // }
31
+ //}
32
+
33
+ //{
34
+ // vm_search_method(ci, cc, recv);
35
+
36
+ // if (check_cfunc(cc->me, rb_obj_equal)) {
37
+ // return recv == obj ? Qtrue : Qfalse;
38
+ // }
39
+ //}
40
+
41
+ return Qundef;
42
+ }
43
+
44
+ VALUE
45
+ llrb_insn_opt_eq(VALUE recv, VALUE obj)
46
+ {
47
+ VALUE val = opt_eq_func(recv, obj);
48
+
49
+ if (val == Qundef) {
50
+ /* other */
51
+ //PUSH(recv);
52
+ //PUSH(obj);
53
+ //CALL_SIMPLE_METHOD(recv);
54
+ return rb_funcall(recv, rb_intern("=="), 1, obj);
55
+ }
56
+ return val;
57
+ }