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,28 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_ge(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_GE, INTEGER_REDEFINED_OP_FLAG)) {
8
+ SIGNED_VALUE a = recv, b = obj;
9
+
10
+ if (a >= b) {
11
+ return Qtrue;
12
+ }
13
+ else {
14
+ return Qfalse;
15
+ }
16
+ }
17
+ else if (FLONUM_2_P(recv, obj) &&
18
+ BASIC_OP_UNREDEFINED_P(BOP_GE, FLOAT_REDEFINED_OP_FLAG)) {
19
+ /* flonum is not NaN */
20
+ return RFLOAT_VALUE(recv) >= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
21
+ }
22
+ else {
23
+ //PUSH(recv);
24
+ //PUSH(obj);
25
+ //CALL_SIMPLE_METHOD(recv);
26
+ return rb_funcall(recv, rb_intern(">="), 1, obj);
27
+ }
28
+ }
@@ -0,0 +1,38 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_gt(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_GT, INTEGER_REDEFINED_OP_FLAG)) {
8
+ SIGNED_VALUE a = recv, b = obj;
9
+
10
+ if (a > b) {
11
+ return Qtrue;
12
+ }
13
+ else {
14
+ return Qfalse;
15
+ }
16
+ }
17
+ else if (FLONUM_2_P(recv, obj) &&
18
+ BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
19
+ /* flonum is not NaN */
20
+ return RFLOAT_VALUE(recv) > RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
21
+ }
22
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
23
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
24
+ // BASIC_OP_UNREDEFINED_P(BOP_GT, FLOAT_REDEFINED_OP_FLAG)) {
25
+ // val = double_cmp_gt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
26
+ // }
27
+ // else {
28
+ // goto INSN_LABEL(normal_dispatch);
29
+ // }
30
+ //}
31
+ else {
32
+ //INSN_LABEL(normal_dispatch):
33
+ //PUSH(recv);
34
+ //PUSH(obj);
35
+ //CALL_SIMPLE_METHOD(recv);
36
+ return rb_funcall(recv, '>', 1, obj);
37
+ }
38
+ }
@@ -0,0 +1,29 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_le(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_LE, INTEGER_REDEFINED_OP_FLAG)) {
8
+ SIGNED_VALUE a = recv, b = obj;
9
+
10
+ if (a <= b) {
11
+ return Qtrue;
12
+ }
13
+ else {
14
+ return Qfalse;
15
+ }
16
+ }
17
+ else if (FLONUM_2_P(recv, obj) &&
18
+ BASIC_OP_UNREDEFINED_P(BOP_LE, FLOAT_REDEFINED_OP_FLAG)) {
19
+ /* flonum is not NaN */
20
+ return RFLOAT_VALUE(recv) <= RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
21
+ }
22
+ else {
23
+ /* other */
24
+ //PUSH(recv);
25
+ //PUSH(obj);
26
+ //CALL_SIMPLE_METHOD(recv);
27
+ return rb_funcall(recv, rb_intern("<="), 1, obj);
28
+ }
29
+ }
@@ -0,0 +1,38 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_lt(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_LT, INTEGER_REDEFINED_OP_FLAG)) {
8
+ SIGNED_VALUE a = recv, b = obj;
9
+
10
+ if (a < b) {
11
+ return Qtrue;
12
+ }
13
+ else {
14
+ return Qfalse;
15
+ }
16
+ }
17
+ else if (FLONUM_2_P(recv, obj) &&
18
+ BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
19
+ /* flonum is not NaN */
20
+ return RFLOAT_VALUE(recv) < RFLOAT_VALUE(obj) ? Qtrue : Qfalse;
21
+ }
22
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
23
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
24
+ // BASIC_OP_UNREDEFINED_P(BOP_LT, FLOAT_REDEFINED_OP_FLAG)) {
25
+ // val = double_cmp_lt(RFLOAT_VALUE(recv), RFLOAT_VALUE(obj));
26
+ // }
27
+ // else {
28
+ // goto INSN_LABEL(normal_dispatch);
29
+ // }
30
+ //}
31
+ else {
32
+ //INSN_LABEL(normal_dispatch):
33
+ //PUSH(recv);
34
+ //PUSH(obj);
35
+ //CALL_SIMPLE_METHOD(recv);
36
+ return rb_funcall(recv, '<', 1, obj);
37
+ }
38
+ }
@@ -0,0 +1,27 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_ltlt(VALUE recv, VALUE obj)
5
+ {
6
+ if (!SPECIAL_CONST_P(recv)) {
7
+ if (RBASIC_CLASS(recv) == rb_cString &&
8
+ BASIC_OP_UNREDEFINED_P(BOP_LTLT, STRING_REDEFINED_OP_FLAG)) {
9
+ return rb_str_concat(recv, obj);
10
+ }
11
+ else if (RBASIC_CLASS(recv) == rb_cArray &&
12
+ BASIC_OP_UNREDEFINED_P(BOP_LTLT, ARRAY_REDEFINED_OP_FLAG)) {
13
+ return rb_ary_push(recv, obj);
14
+ }
15
+ else {
16
+ //goto INSN_LABEL(normal_dispatch);
17
+ return rb_funcall(recv, rb_intern("<<"), 1, obj);
18
+ }
19
+ }
20
+ else {
21
+ //INSN_LABEL(normal_dispatch):
22
+ //PUSH(recv);
23
+ //PUSH(obj);
24
+ //CALL_SIMPLE_METHOD(recv);
25
+ return rb_funcall(recv, rb_intern("<<"), 1, obj);
26
+ }
27
+ }
@@ -0,0 +1,36 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_minus(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_MINUS, INTEGER_REDEFINED_OP_FLAG)) {
8
+ long a, b, c;
9
+
10
+ a = FIX2LONG(recv);
11
+ b = FIX2LONG(obj);
12
+ c = a - b;
13
+ return LONG2NUM(c);
14
+ }
15
+ else if (FLONUM_2_P(recv, obj) &&
16
+ BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
17
+ return DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
18
+ }
19
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
20
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
21
+ // BASIC_OP_UNREDEFINED_P(BOP_MINUS, FLOAT_REDEFINED_OP_FLAG)) {
22
+ // val = DBL2NUM(RFLOAT_VALUE(recv) - RFLOAT_VALUE(obj));
23
+ // }
24
+ // else {
25
+ // goto INSN_LABEL(normal_dispatch);
26
+ // }
27
+ //}
28
+ else {
29
+ /* other */
30
+ //INSN_LABEL(normal_dispatch):
31
+ //PUSH(recv);
32
+ //PUSH(obj);
33
+ //CALL_SIMPLE_METHOD(recv);
34
+ return rb_funcall(recv, '-', 1, obj);
35
+ }
36
+ }
@@ -0,0 +1,32 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_mod(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_MOD, 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_mod_fix(recv, obj);
11
+ }
12
+ else if (FLONUM_2_P(recv, obj) &&
13
+ BASIC_OP_UNREDEFINED_P(BOP_MOD, FLOAT_REDEFINED_OP_FLAG)) {
14
+ return DBL2NUM(ruby_float_mod(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_MOD, FLOAT_REDEFINED_OP_FLAG)) {
19
+ // val = DBL2NUM(ruby_float_mod(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
+ }
31
+ return rb_funcall(recv, '%', 1, obj);
32
+ }
@@ -0,0 +1,30 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_mult(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_MULT, INTEGER_REDEFINED_OP_FLAG)) {
8
+ return rb_fix_mul_fix(recv, obj);
9
+ }
10
+ else if (FLONUM_2_P(recv, obj) &&
11
+ BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
12
+ return DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
13
+ }
14
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
15
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
16
+ // BASIC_OP_UNREDEFINED_P(BOP_MULT, FLOAT_REDEFINED_OP_FLAG)) {
17
+ // val = DBL2NUM(RFLOAT_VALUE(recv) * RFLOAT_VALUE(obj));
18
+ // }
19
+ // else {
20
+ // goto INSN_LABEL(normal_dispatch);
21
+ // }
22
+ //}
23
+ else {
24
+ //INSN_LABEL(normal_dispatch):
25
+ //PUSH(recv);
26
+ //PUSH(obj);
27
+ //CALL_SIMPLE_METHOD(recv);
28
+ return rb_funcall(recv, '*', 1, obj);
29
+ }
30
+ }
@@ -0,0 +1,103 @@
1
+ #include "cruby.h"
2
+
3
+ void vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE recv);
4
+
5
+ inline VALUE
6
+ rb_obj_equal(VALUE obj1, VALUE obj2)
7
+ {
8
+ if (obj1 == obj2) return Qtrue;
9
+ return Qfalse;
10
+ }
11
+
12
+ #define id_eq idEq
13
+ inline VALUE
14
+ rb_obj_not_equal(VALUE obj1, VALUE obj2)
15
+ {
16
+ VALUE result = rb_funcall(obj1, id_eq, 1, obj2);
17
+ return RTEST(result) ? Qfalse : Qtrue;
18
+ }
19
+
20
+ static inline int
21
+ check_cfunc(const rb_callable_method_entry_t *me, VALUE (*func)())
22
+ {
23
+ if (me && me->def->type == VM_METHOD_TYPE_CFUNC &&
24
+ me->def->body.cfunc.func == func) {
25
+ return 1;
26
+ }
27
+ else {
28
+ return 0;
29
+ }
30
+ }
31
+
32
+ static inline VALUE
33
+ opt_eq_func(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc)
34
+ {
35
+ if (FIXNUM_2_P(recv, obj) &&
36
+ BASIC_OP_UNREDEFINED_P(BOP_EQ, INTEGER_REDEFINED_OP_FLAG)) {
37
+ return (recv == obj) ? Qtrue : Qfalse;
38
+ }
39
+ else if (FLONUM_2_P(recv, obj) &&
40
+ BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
41
+ return (recv == obj) ? Qtrue : Qfalse;
42
+ }
43
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
44
+ // if (RBASIC_CLASS(recv) == rb_cFloat &&
45
+ // RBASIC_CLASS(obj) == rb_cFloat &&
46
+ // BASIC_OP_UNREDEFINED_P(BOP_EQ, FLOAT_REDEFINED_OP_FLAG)) {
47
+ // double a = RFLOAT_VALUE(recv);
48
+ // double b = RFLOAT_VALUE(obj);
49
+
50
+ // if (isnan(a) || isnan(b)) {
51
+ // return Qfalse;
52
+ // }
53
+ // return (a == b) ? Qtrue : Qfalse;
54
+ // }
55
+ // else if (RBASIC_CLASS(recv) == rb_cString &&
56
+ // RBASIC_CLASS(obj) == rb_cString &&
57
+ // BASIC_OP_UNREDEFINED_P(BOP_EQ, STRING_REDEFINED_OP_FLAG)) {
58
+ // return rb_str_equal(recv, obj);
59
+ // }
60
+ //}
61
+
62
+ {
63
+ vm_search_method(ci, cc, recv);
64
+
65
+ if (check_cfunc(cc->me, rb_obj_equal)) {
66
+ return recv == obj ? Qtrue : Qfalse;
67
+ }
68
+ }
69
+
70
+ return Qundef;
71
+ }
72
+
73
+ static inline VALUE
74
+ _llrb_insn_opt_neq(VALUE recv, VALUE obj, CALL_INFO ci, CALL_CACHE cc, CALL_INFO ci_eq, CALL_CACHE cc_eq)
75
+ {
76
+ //extern VALUE rb_obj_not_equal(VALUE obj1, VALUE obj2);
77
+ vm_search_method(ci, cc, recv);
78
+
79
+ VALUE val = Qundef;
80
+
81
+ if (check_cfunc(cc->me, rb_obj_not_equal)) {
82
+ val = opt_eq_func(recv, obj, ci_eq, cc_eq);
83
+
84
+ if (val != Qundef) {
85
+ val = RTEST(val) ? Qfalse : Qtrue;
86
+ }
87
+ }
88
+
89
+ if (val == Qundef) {
90
+ /* other */
91
+ //PUSH(recv);
92
+ //PUSH(obj);
93
+ //CALL_SIMPLE_METHOD(recv);
94
+ return rb_funcall(recv, rb_intern("!="), 1, obj);
95
+ }
96
+ return val;
97
+ }
98
+
99
+ VALUE
100
+ llrb_insn_opt_neq(VALUE recv, VALUE obj, VALUE ci, VALUE cc, VALUE ci_eq, VALUE cc_eq)
101
+ {
102
+ return _llrb_insn_opt_neq(recv, obj, (CALL_INFO)ci, (CALL_CACHE)cc, (CALL_INFO)ci_eq, (CALL_CACHE)cc_eq);
103
+ }
@@ -0,0 +1,48 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_plus(VALUE recv, VALUE obj)
5
+ {
6
+ if (FIXNUM_2_P(recv, obj) &&
7
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS,INTEGER_REDEFINED_OP_FLAG)) {
8
+ /* fixnum + fixnum */
9
+ #ifndef LONG_LONG_VALUE
10
+ VALUE msb = (VALUE)1 << ((sizeof(VALUE) * CHAR_BIT) - 1);
11
+ VALUE val = recv - 1 + obj;
12
+ if ((~(recv ^ obj) & (recv ^ val)) & msb) {
13
+ return rb_int2big((SIGNED_VALUE)((val>>1) | (recv & msb)));
14
+ }
15
+ return val;
16
+ #else
17
+ return LONG2NUM(FIX2LONG(recv) + FIX2LONG(obj));
18
+ #endif
19
+ }
20
+ else if (FLONUM_2_P(recv, obj) &&
21
+ BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
22
+ return DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
23
+ }
24
+ //else if (!SPECIAL_CONST_P(recv) && !SPECIAL_CONST_P(obj)) {
25
+ // if (RBASIC_CLASS(recv) == rb_cFloat && RBASIC_CLASS(obj) == rb_cFloat &&
26
+ // BASIC_OP_UNREDEFINED_P(BOP_PLUS, FLOAT_REDEFINED_OP_FLAG)) {
27
+ // val = DBL2NUM(RFLOAT_VALUE(recv) + RFLOAT_VALUE(obj));
28
+ // }
29
+ // else if (RBASIC_CLASS(recv) == rb_cString && RBASIC_CLASS(obj) == rb_cString &&
30
+ // BASIC_OP_UNREDEFINED_P(BOP_PLUS, STRING_REDEFINED_OP_FLAG)) {
31
+ // val = rb_str_plus(recv, obj);
32
+ // }
33
+ // else if (RBASIC_CLASS(recv) == rb_cArray &&
34
+ // BASIC_OP_UNREDEFINED_P(BOP_PLUS, ARRAY_REDEFINED_OP_FLAG)) {
35
+ // val = rb_ary_plus(recv, obj);
36
+ // }
37
+ // else {
38
+ // goto INSN_LABEL(normal_dispatch);
39
+ // }
40
+ //}
41
+ else {
42
+ //INSN_LABEL(normal_dispatch):
43
+ //PUSH(recv);
44
+ //PUSH(obj);
45
+ //CALL_SIMPLE_METHOD(recv);
46
+ return rb_funcall(recv, '+', 1, obj);
47
+ }
48
+ }
@@ -0,0 +1,45 @@
1
+ #include "cruby.h"
2
+
3
+ static inline void
4
+ _llrb_push_result(rb_control_frame_t *cfp, VALUE result)
5
+ {
6
+ // PUSH(result)
7
+ *(cfp->sp) = result;
8
+ cfp->sp += 1;
9
+ }
10
+
11
+ #define CALL_METHOD(calling, ci, cc) (*(cc)->call)(th, cfp, (calling), (ci), (cc))
12
+ void vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE recv);
13
+ VALUE vm_exec(rb_thread_t *th);
14
+ VALUE // TODO: refactor with invokesuper
15
+ llrb_insn_opt_send_without_block(VALUE th_value, VALUE cfp_value, VALUE ci_value, VALUE cc_value, unsigned int stack_size, ...)
16
+ {
17
+ rb_thread_t *th = (rb_thread_t *)th_value;
18
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_value;
19
+ CALL_INFO ci = (CALL_INFO)ci_value;
20
+ CALL_CACHE cc = (CALL_CACHE)cc_value;
21
+
22
+ VALUE recv = Qnil;
23
+ va_list ar;
24
+ va_start(ar, stack_size);
25
+ for (unsigned int i = 0; i < stack_size; i++) {
26
+ VALUE val = va_arg(ar, VALUE);
27
+ if (i == 0) recv = val;
28
+ _llrb_push_result(cfp, val);
29
+ }
30
+ va_end(ar);
31
+
32
+ vm_search_method(ci, cc, recv);
33
+
34
+ struct rb_calling_info calling;
35
+ calling.block_handler = VM_BLOCK_HANDLER_NONE;
36
+ calling.argc = ci->orig_argc;
37
+ calling.recv = recv;
38
+
39
+ VALUE result = CALL_METHOD(&calling, ci, cc);
40
+ if (result == Qundef) {
41
+ VM_ENV_FLAGS_SET(th->cfp->ep, VM_FRAME_FLAG_FINISH);
42
+ return vm_exec(th);
43
+ }
44
+ return result;
45
+ }