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,12 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE
4
+ llrb_insn_opt_str_freeze(VALUE str)
5
+ {
6
+ if (BASIC_OP_UNREDEFINED_P(BOP_FREEZE, STRING_REDEFINED_OP_FLAG)) {
7
+ return str;
8
+ }
9
+ else {
10
+ return rb_funcall(rb_str_resurrect(str), idFreeze, 0);
11
+ }
12
+ }
@@ -0,0 +1,23 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_get_cbase(const VALUE *ep);
4
+ VALUE vm_get_const_base(const VALUE *ep);
5
+ VALUE
6
+ llrb_insn_putspecialobject(rb_num_t value_type) {
7
+ enum vm_special_object_type type = (enum vm_special_object_type)value_type;
8
+
9
+ switch (type) {
10
+ case VM_SPECIAL_OBJECT_VMCORE:
11
+ return rb_mRubyVMFrozenCore;
12
+ case VM_SPECIAL_OBJECT_CBASE: {
13
+ rb_thread_t *th = GET_THREAD();
14
+ return vm_get_cbase(th->cfp->ep);
15
+ }
16
+ case VM_SPECIAL_OBJECT_CONST_BASE: {
17
+ rb_thread_t *th = GET_THREAD();
18
+ return vm_get_const_base(th->cfp->ep);
19
+ }
20
+ default:
21
+ rb_bug("putspecialobject insn: unknown value_type");
22
+ }
23
+ }
@@ -0,0 +1,49 @@
1
+ #include "cruby.h"
2
+
3
+ #define CALL_METHOD(calling, ci, cc) (*(cc)->call)(th, cfp, (calling), (ci), (cc))
4
+ void vm_search_method(const struct rb_call_info *ci, struct rb_call_cache *cc, VALUE recv);
5
+ VALUE vm_exec(rb_thread_t *th);
6
+ void vm_caller_setup_arg_block(const rb_thread_t *th, rb_control_frame_t *reg_cfp,
7
+ struct rb_calling_info *calling, const struct rb_call_info *ci, rb_iseq_t *blockiseq, const int is_super);
8
+
9
+ static inline void
10
+ _llrb_push_result(rb_control_frame_t *cfp, VALUE result)
11
+ {
12
+ // PUSH(result)
13
+ *(cfp->sp) = result;
14
+ cfp->sp += 1;
15
+ }
16
+
17
+ VALUE
18
+ llrb_insn_send(VALUE th_v, VALUE cfp_v, VALUE ci_v, VALUE cc_v, VALUE blockiseq_v, unsigned int stack_size, ...)
19
+ {
20
+ rb_thread_t *th = (rb_thread_t *)th_v;
21
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
22
+ CALL_INFO ci = (CALL_INFO)ci_v;
23
+ CALL_CACHE cc = (CALL_CACHE)cc_v;
24
+ ISEQ blockiseq = (ISEQ)blockiseq_v;
25
+
26
+ VALUE recv = Qnil;
27
+ va_list ar;
28
+ va_start(ar, stack_size);
29
+ for (unsigned int i = 0; i < stack_size; i++) {
30
+ VALUE val = va_arg(ar, VALUE);
31
+ if (i == 0) recv = val;
32
+ _llrb_push_result(cfp, val);
33
+ }
34
+ va_end(ar);
35
+
36
+ struct rb_calling_info calling;
37
+
38
+ vm_caller_setup_arg_block(th, cfp, &calling, ci, blockiseq, 0);
39
+ calling.argc = ci->orig_argc;
40
+ calling.recv = recv;
41
+ vm_search_method(ci, cc, recv);
42
+
43
+ VALUE result = CALL_METHOD(&calling, ci, cc);
44
+ if (result == Qundef) {
45
+ VM_ENV_FLAGS_SET(th->cfp->ep, VM_FRAME_FLAG_FINISH);
46
+ return vm_exec(th);
47
+ }
48
+ return result;
49
+ }
@@ -0,0 +1,19 @@
1
+ #include "cruby.h"
2
+
3
+ rb_cref_t * rb_vm_get_cref(const VALUE *ep);
4
+ static inline void
5
+ vm_ensure_not_refinement_module(VALUE self)
6
+ {
7
+ if (RB_TYPE_P(self, T_MODULE) && FL_TEST(self, RMODULE_IS_REFINEMENT)) {
8
+ rb_warn("not defined at the refinement, but at the outer class/module");
9
+ }
10
+ }
11
+
12
+ VALUE vm_get_cvar_base(const rb_cref_t *cref, rb_control_frame_t *cfp);
13
+ void
14
+ llrb_insn_setclassvariable(VALUE cfp_v, ID id, VALUE val)
15
+ {
16
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
17
+ vm_ensure_not_refinement_module(cfp->self);
18
+ rb_cvar_set(vm_get_cvar_base(rb_vm_get_cref(cfp->ep), cfp), id, val);
19
+ }
@@ -0,0 +1,23 @@
1
+ #include "cruby.h"
2
+
3
+ static inline void
4
+ vm_check_if_namespace(VALUE klass)
5
+ {
6
+ if (!RB_TYPE_P(klass, T_CLASS) && !RB_TYPE_P(klass, T_MODULE)) {
7
+ rb_raise(rb_eTypeError, "%+"PRIsVALUE" is not a class/module", klass);
8
+ }
9
+ }
10
+ static inline void
11
+ vm_ensure_not_refinement_module(VALUE self)
12
+ {
13
+ if (RB_TYPE_P(self, T_MODULE) && FL_TEST(self, RMODULE_IS_REFINEMENT)) {
14
+ rb_warn("not defined at the refinement, but at the outer class/module");
15
+ }
16
+ }
17
+ // https://github.com/ruby/ruby/blob/v2_4_1/insns.def#L201-L223
18
+ void
19
+ llrb_insn_setconstant(VALUE self, VALUE cbase, ID id, VALUE val) {
20
+ vm_check_if_namespace(cbase);
21
+ vm_ensure_not_refinement_module(self);
22
+ rb_const_set(cbase, id, val);
23
+ }
@@ -0,0 +1,48 @@
1
+ #include "cruby.h"
2
+
3
+ static inline VALUE
4
+ vm_setivar(VALUE obj, ID id, VALUE val, IC ic, struct rb_call_cache *cc, int is_attr)
5
+ {
6
+ rb_check_frozen(obj);
7
+
8
+ if (LIKELY(RB_TYPE_P(obj, T_OBJECT))) {
9
+ VALUE klass = RBASIC(obj)->klass;
10
+ st_data_t index;
11
+
12
+ if (LIKELY(
13
+ (!is_attr && ic->ic_serial == RCLASS_SERIAL(klass)) ||
14
+ (is_attr && cc->aux.index > 0))) {
15
+ VALUE *ptr = ROBJECT_IVPTR(obj);
16
+ index = !is_attr ? ic->ic_value.index : cc->aux.index-1;
17
+
18
+ if (index < ROBJECT_NUMIV(obj)) {
19
+ RB_OBJ_WRITE(obj, &ptr[index], val);
20
+ return val; /* inline cache hit */
21
+ }
22
+ }
23
+ else {
24
+ struct st_table *iv_index_tbl = ROBJECT_IV_INDEX_TBL(obj);
25
+
26
+ if (iv_index_tbl && st_lookup(iv_index_tbl, (st_data_t)id, &index)) {
27
+ if (!is_attr) {
28
+ ic->ic_value.index = index;
29
+ ic->ic_serial = RCLASS_SERIAL(klass);
30
+ }
31
+ else if (index >= INT_MAX) {
32
+ rb_raise(rb_eArgError, "too many instance variables");
33
+ }
34
+ else {
35
+ cc->aux.index = (int)(index + 1);
36
+ }
37
+ }
38
+ /* fall through */
39
+ }
40
+ }
41
+ return rb_ivar_set(obj, id, val);
42
+ }
43
+
44
+ void
45
+ llrb_insn_setinstancevariable(VALUE obj, ID id, VALUE val, VALUE ic_v)
46
+ {
47
+ vm_setivar(obj, id, val, (IC)ic_v, 0, 0);
48
+ }
@@ -0,0 +1,16 @@
1
+ #include "cruby.h"
2
+
3
+ void rb_vm_env_write(const VALUE *ep, int index, VALUE v);
4
+
5
+ void
6
+ llrb_insn_setlocal(VALUE cfp_v, lindex_t idx, rb_num_t level, VALUE val)
7
+ {
8
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
9
+ int i, lev = (int)level;
10
+ const VALUE *ep = cfp->ep;
11
+
12
+ for (i = 0; i < lev; i++) {
13
+ ep = GET_PREV_EP(ep);
14
+ }
15
+ rb_vm_env_write(ep, -(int)idx, val);
16
+ }
@@ -0,0 +1,9 @@
1
+ #include "cruby.h"
2
+
3
+ void rb_vm_env_write(const VALUE *ep, int index, VALUE v);
4
+ void
5
+ llrb_insn_setlocal_level0(VALUE cfp_v, lindex_t idx, VALUE val)
6
+ {
7
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
8
+ rb_vm_env_write(cfp->ep, -(int)idx, val);
9
+ }
@@ -0,0 +1,10 @@
1
+ #include "cruby.h"
2
+
3
+ void rb_vm_env_write(const VALUE *ep, int index, VALUE v);
4
+
5
+ void
6
+ llrb_insn_setlocal_level1(VALUE cfp_v, lindex_t idx, VALUE val)
7
+ {
8
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
9
+ rb_vm_env_write(GET_PREV_EP(cfp->ep), -(int)idx, val);
10
+ }
@@ -0,0 +1,15 @@
1
+ #include "cruby.h"
2
+
3
+ void lep_svar_set(rb_thread_t *th, const VALUE *lep, rb_num_t key, VALUE val);
4
+ void
5
+ llrb_insn_setspecial(rb_num_t key, VALUE obj)
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
+
14
+ lep_svar_set(th, ep, key, obj);
15
+ }
@@ -0,0 +1,13 @@
1
+ #include "cruby.h"
2
+
3
+ // https://github.com/ruby/ruby/blob/v2_4_1/insns.def#L515-L534
4
+ VALUE
5
+ llrb_insn_splatarray(VALUE ary, VALUE flag) {
6
+ VALUE tmp = rb_check_convert_type(ary, T_ARRAY, "Array", "to_a");
7
+ if (NIL_P(tmp)) {
8
+ tmp = rb_ary_new3(1, ary);
9
+ } else if (RTEST(flag)) {
10
+ tmp = rb_ary_dup(tmp);
11
+ }
12
+ return tmp;
13
+ }
@@ -0,0 +1,11 @@
1
+ #include "cruby.h"
2
+
3
+ VALUE vm_throw(rb_thread_t *th, rb_control_frame_t *reg_cfp, rb_num_t throw_state, VALUE throwobj);
4
+ void
5
+ llrb_insn_throw(VALUE th_value, VALUE cfp_value, rb_num_t throw_state, VALUE throwobj)
6
+ {
7
+ rb_thread_t *th = (rb_thread_t *)th_value;
8
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_value;
9
+ RUBY_VM_CHECK_INTS(th);
10
+ th->errinfo = vm_throw(th, cfp, throw_state, throwobj);
11
+ }
@@ -0,0 +1,37 @@
1
+ #include "cruby.h"
2
+ #include "cruby/probes_helper.h"
3
+
4
+ // TODO: Use vm_dtrace after Ruby 2.5
5
+ static inline void
6
+ _llrb_insn_trace(rb_thread_t *th, rb_control_frame_t *cfp, rb_event_flag_t flag, VALUE val)
7
+ {
8
+ if (RUBY_DTRACE_METHOD_ENTRY_ENABLED() ||
9
+ RUBY_DTRACE_METHOD_RETURN_ENABLED() ||
10
+ RUBY_DTRACE_CMETHOD_ENTRY_ENABLED() ||
11
+ RUBY_DTRACE_CMETHOD_RETURN_ENABLED()) {
12
+
13
+ switch (flag) {
14
+ case RUBY_EVENT_CALL:
15
+ RUBY_DTRACE_METHOD_ENTRY_HOOK(th, 0, 0);
16
+ break;
17
+ case RUBY_EVENT_C_CALL:
18
+ RUBY_DTRACE_CMETHOD_ENTRY_HOOK(th, 0, 0);
19
+ break;
20
+ case RUBY_EVENT_RETURN:
21
+ RUBY_DTRACE_METHOD_RETURN_HOOK(th, 0, 0);
22
+ break;
23
+ case RUBY_EVENT_C_RETURN:
24
+ RUBY_DTRACE_CMETHOD_RETURN_HOOK(th, 0, 0);
25
+ break;
26
+ }
27
+ }
28
+
29
+ // TODO: Confirm it works!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
30
+ // Especially for :line event. We may need to update program counter.
31
+ EXEC_EVENT_HOOK(th, flag, cfp->self, 0, 0, 0 /* id and klass are resolved at callee */, val);
32
+ }
33
+ void
34
+ llrb_insn_trace(VALUE th, VALUE cfp, rb_event_flag_t flag, VALUE val)
35
+ {
36
+ _llrb_insn_trace((rb_thread_t *)th, (rb_control_frame_t *)cfp, flag, val);
37
+ }
@@ -0,0 +1,14 @@
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
+ void
11
+ llrb_push_result(VALUE cfp, VALUE result)
12
+ {
13
+ _llrb_push_result((rb_control_frame_t *)cfp, result);
14
+ }
@@ -0,0 +1,12 @@
1
+ #include "cruby.h"
2
+
3
+ static inline VALUE
4
+ _llrb_self_from_cfp(rb_control_frame_t *cfp)
5
+ {
6
+ return cfp->self;
7
+ }
8
+ VALUE
9
+ llrb_self_from_cfp(VALUE cfp)
10
+ {
11
+ return _llrb_self_from_cfp((rb_control_frame_t *)cfp);
12
+ }
@@ -0,0 +1,8 @@
1
+ #include "cruby.h"
2
+
3
+ void
4
+ llrb_set_pc(VALUE cfp_v, VALUE pc_v)
5
+ {
6
+ rb_control_frame_t *cfp = (rb_control_frame_t *)cfp_v;
7
+ cfp->pc = (VALUE *)pc_v;
8
+ }
@@ -0,0 +1,2 @@
1
+ require 'llrb/version'
2
+ require 'llrb/jit'
@@ -0,0 +1,76 @@
1
+ require 'llrb/llrb'
2
+
3
+ module LLRB
4
+ module JIT
5
+ # Compile method to native code
6
+ #
7
+ # @param [Object] recv - receiver of method to be compiled
8
+ # @param [String,Symbol] method - precompiled method name
9
+ # @return [Boolean] - return true if precompiled
10
+ def self.compile(recv, name)
11
+ compile_proc(recv.method(name))
12
+ end
13
+
14
+ def self.compile_proc(func)
15
+ iseqw = RubyVM::InstructionSequence.of(func)
16
+ return false if iseqw.nil? # method defined with C function can't be compiled
17
+
18
+ #puts "#{iseqw.disasm}\n"
19
+ compile_iseq(iseqw)
20
+ end
21
+
22
+ # Preview compiled method in LLVM IR
23
+ #
24
+ # @param [Object] recv - receiver of method to be compiled
25
+ # @param [String,Symbol] method_name - precompiled method name
26
+ def self.preview(recv, name)
27
+ method = recv.method(name)
28
+ iseqw = RubyVM::InstructionSequence.of(method)
29
+ return false if iseqw.nil?
30
+
31
+ puts "#{iseqw.disasm}\n"
32
+ preview_iseq(iseqw)
33
+ end
34
+
35
+ def self.compiled?(recv, name)
36
+ method = recv.method(name)
37
+ iseqw = RubyVM::InstructionSequence.of(method)
38
+ return false if iseqw.nil?
39
+
40
+ is_compiled(iseqw)
41
+ end
42
+
43
+ def self.start
44
+ hook_stop
45
+ start_internal
46
+ end
47
+
48
+ # Hook JIT stop at exit to safely shutdown Ruby VM. JIT touches Ruby VM and
49
+ # it should not run after Ruby VM destruction. Otherwise it will cause SEGV.
50
+ def self.hook_stop
51
+ return if defined?(@hook_stop)
52
+ @hook_stop = true
53
+ at_exit { LLRB::JIT.stop }
54
+ end
55
+ private_class_method :hook_stop
56
+
57
+ # Followings are defined in ext/llrb/llrb.cc
58
+
59
+ # @param [RubyVM::InstructionSequence] iseqw - RubyVM::InstructionSequence instance
60
+ # @return [Boolean] return true if compiled
61
+ private_class_method :compile_iseq
62
+
63
+ # @param [RubyVM::InstructionSequence] iseqw - RubyVM::InstructionSequence instance
64
+ # @return [Boolean] return true if compiled
65
+ private_class_method :preview_iseq
66
+
67
+ # @param [RubyVM::InstructionSequence] iseqw - RubyVM::InstructionSequence instance
68
+ # @return [Boolean] return true if compiled
69
+ private_class_method :is_compiled
70
+
71
+ # This does not hook stop, but it may cause SEGV if JIT runs after Ruby VM is shut down.
72
+ # To ensure JIT will be stopped on exit, you should use .start instead.
73
+ # @return [Boolean] return true if started JIT
74
+ private_class_method :start_internal
75
+ end
76
+ end
@@ -0,0 +1,2 @@
1
+ require 'llrb'
2
+ LLRB::JIT.start
@@ -0,0 +1,3 @@
1
+ module LLRB
2
+ VERSION = '0.0.1'
3
+ end
@@ -0,0 +1,48 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'llrb/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = 'llrb'
8
+ spec.version = LLRB::VERSION
9
+ spec.authors = ['Takashi Kokubun']
10
+ spec.email = ['takashikkbn@gmail.com']
11
+
12
+ spec.summary = 'LLRB is LLVM-based JIT compiler for Ruby. Note that this gem can be only installed to fork of CRuby.'
13
+ spec.description = 'LLRB is LLVM-based JIT compiler for Ruby. Note that this gem can be only installed to fork of CRuby.'
14
+ spec.homepage = 'https://github.com/k0kubun/llrb'
15
+ spec.license = 'MIT'
16
+
17
+ ccans = Dir.chdir("#{__dir__}/ext/llrb/cruby") { Dir.glob("ccan/**/*.h") }
18
+ cruby = (ccans + %w[
19
+ internal.h
20
+ iseq.h
21
+ method.h
22
+ node.h
23
+ probes_helper.h
24
+ ruby_assert.h
25
+ ruby_atomic.h
26
+ thread_pthread.h
27
+ vm_core.h
28
+ vm_debug.h
29
+ vm_exec.h
30
+ vm_opts.h
31
+ ]).map { |f| "ext/llrb/cruby/#{f}" }
32
+
33
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
34
+ f.match(%r{^(test|spec|features)/})
35
+ end + cruby
36
+
37
+ spec.bindir = 'exe'
38
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
39
+ spec.require_paths = ['lib']
40
+ spec.extensions = ['ext/llrb/extconf.rb']
41
+
42
+ spec.add_development_dependency 'benchmark-ips'
43
+ spec.add_development_dependency 'bundler'
44
+ spec.add_development_dependency 'pry'
45
+ spec.add_development_dependency 'rake'
46
+ spec.add_development_dependency 'rake-compiler'
47
+ spec.add_development_dependency 'rspec', '~> 3.0'
48
+ end