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