llrb 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }