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.
- checksums.yaml +7 -0
- data/.gitignore +21 -0
- data/.gitmodules +4 -0
- data/.rspec +2 -0
- data/.travis.yml +5 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +56 -0
- data/README.md +311 -0
- data/Rakefile +30 -0
- data/bin/bm_app_fib +41 -0
- data/bin/bm_empty_method +33 -0
- data/bin/bm_loop_while +27 -0
- data/bin/bm_plus +33 -0
- data/bin/console +14 -0
- data/bin/loop_while.rb +5 -0
- data/bin/setup +8 -0
- data/ext/llrb/cfg.h +124 -0
- data/ext/llrb/compiler.c +987 -0
- data/ext/llrb/compiler/funcs.h +164 -0
- data/ext/llrb/compiler/stack.h +43 -0
- data/ext/llrb/cruby.h +42 -0
- data/ext/llrb/cruby/ccan/build_assert/build_assert.h +40 -0
- data/ext/llrb/cruby/ccan/check_type/check_type.h +63 -0
- data/ext/llrb/cruby/ccan/container_of/container_of.h +142 -0
- data/ext/llrb/cruby/ccan/list/list.h +773 -0
- data/ext/llrb/cruby/ccan/str/str.h +16 -0
- data/ext/llrb/cruby/internal.h +1774 -0
- data/ext/llrb/cruby/iseq.h +252 -0
- data/ext/llrb/cruby/method.h +213 -0
- data/ext/llrb/cruby/node.h +520 -0
- data/ext/llrb/cruby/probes_helper.h +43 -0
- data/ext/llrb/cruby/ruby_assert.h +54 -0
- data/ext/llrb/cruby/ruby_atomic.h +233 -0
- data/ext/llrb/cruby/thread_pthread.h +54 -0
- data/ext/llrb/cruby/vm_core.h +1646 -0
- data/ext/llrb/cruby/vm_debug.h +37 -0
- data/ext/llrb/cruby/vm_exec.h +182 -0
- data/ext/llrb/cruby/vm_opts.h +57 -0
- data/ext/llrb/cruby_extra/id.h +220 -0
- data/ext/llrb/cruby_extra/insns.inc +113 -0
- data/ext/llrb/cruby_extra/insns_info.inc +796 -0
- data/ext/llrb/cruby_extra/probes.h +80 -0
- data/ext/llrb/extconf.rb +102 -0
- data/ext/llrb/llrb.c +148 -0
- data/ext/llrb/optimizer.cc +118 -0
- data/ext/llrb/parser.c +191 -0
- data/ext/llrb/profiler.c +336 -0
- data/ext/llrb_insn_checkkeyword.c +20 -0
- data/ext/llrb_insn_checkmatch.c +28 -0
- data/ext/llrb_insn_concatarray.c +23 -0
- data/ext/llrb_insn_concatstrings.c +21 -0
- data/ext/llrb_insn_defined.c +9 -0
- data/ext/llrb_insn_getclassvariable.c +10 -0
- data/ext/llrb_insn_getinstancevariable.c +44 -0
- data/ext/llrb_insn_getlocal.c +14 -0
- data/ext/llrb_insn_getlocal_level0.c +8 -0
- data/ext/llrb_insn_getlocal_level1.c +8 -0
- data/ext/llrb_insn_getspecial.c +14 -0
- data/ext/llrb_insn_invokeblock.c +39 -0
- data/ext/llrb_insn_invokesuper.c +47 -0
- data/ext/llrb_insn_opt_aref.c +25 -0
- data/ext/llrb_insn_opt_aset.c +28 -0
- data/ext/llrb_insn_opt_div.c +32 -0
- data/ext/llrb_insn_opt_eq.c +57 -0
- data/ext/llrb_insn_opt_ge.c +28 -0
- data/ext/llrb_insn_opt_gt.c +38 -0
- data/ext/llrb_insn_opt_le.c +29 -0
- data/ext/llrb_insn_opt_lt.c +38 -0
- data/ext/llrb_insn_opt_ltlt.c +27 -0
- data/ext/llrb_insn_opt_minus.c +36 -0
- data/ext/llrb_insn_opt_mod.c +32 -0
- data/ext/llrb_insn_opt_mult.c +30 -0
- data/ext/llrb_insn_opt_neq.c +103 -0
- data/ext/llrb_insn_opt_plus.c +48 -0
- data/ext/llrb_insn_opt_send_without_block.c +45 -0
- data/ext/llrb_insn_opt_str_freeze.c +12 -0
- data/ext/llrb_insn_putspecialobject.c +23 -0
- data/ext/llrb_insn_send.c +49 -0
- data/ext/llrb_insn_setclassvariable.c +19 -0
- data/ext/llrb_insn_setconstant.c +23 -0
- data/ext/llrb_insn_setinstancevariable.c +48 -0
- data/ext/llrb_insn_setlocal.c +16 -0
- data/ext/llrb_insn_setlocal_level0.c +9 -0
- data/ext/llrb_insn_setlocal_level1.c +10 -0
- data/ext/llrb_insn_setspecial.c +15 -0
- data/ext/llrb_insn_splatarray.c +13 -0
- data/ext/llrb_insn_throw.c +11 -0
- data/ext/llrb_insn_trace.c +37 -0
- data/ext/llrb_push_result.c +14 -0
- data/ext/llrb_self_from_cfp.c +12 -0
- data/ext/llrb_set_pc.c +8 -0
- data/lib/llrb.rb +2 -0
- data/lib/llrb/jit.rb +76 -0
- data/lib/llrb/start.rb +2 -0
- data/lib/llrb/version.rb +3 -0
- data/llrb.gemspec +48 -0
- data/wercker.yml +31 -0
- 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
|
+
}
|