hacks 0.0.1 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: bc7490b844554dbfab5a6bbb8b7ccffc78707533c1da479c37d9d95d05e4edea
4
- data.tar.gz: b9be1db5fa2b2bcf8489fe7dc3dc2e777db4f272d0d1cc57dc58f00af3a0921d
3
+ metadata.gz: 9d864adfb10ffe7141efe44a825a6691a50564bb5762a81d0ab970afe264eb34
4
+ data.tar.gz: a653799f9f87b99e9d83c893aa793da7f8152dbddabc9be987be45faac2cb527
5
5
  SHA512:
6
- metadata.gz: cb87833249d0fae12c00e87c9d9b2321b7c3ec9404960176d1b7fc2f2fb2f33ed6259c0a11bca8fc26a218f6a8112e8d7a0aee809908526598b09dcaa84a4374
7
- data.tar.gz: 410ab0b742089dedbc90c7cd9f3e359debb9e3f150502eed99905f90d94b04ec8429b1b075c46e7a93da42b07ac1e9a288fac672b0dd01ef664bdb447caa0173
6
+ metadata.gz: 94a16bcccc2be2fe57c52f55e4b8370d1a4a056c42fd8ceeefc7e9d8a8992d0a5ae8021abd0d7a78278c094b56485b61817ba9ae46f3e98a7a6a23b187ce27d8
7
+ data.tar.gz: 537c8567c67ccc38f9df2f0e4eacaa5ea1ed7a5ddf3c95990ed9bb619e5db0657905f72cfccf9dd275ec1aaa7105e7edf03f068326c865147706340a6082ebc3
data/Rakefile CHANGED
@@ -1,4 +1,60 @@
1
-
1
+ require "rake/clean"
2
2
  require 'rake/extensiontask'
3
+
4
+ task :compile => "ext/hacks/structs.rb"
3
5
  Rake::ExtensionTask.new("hacks")
4
6
 
7
+ CLOBBER.include "ext/hacks/structs.rb"
8
+
9
+ def walk doc, &blk
10
+ yield doc
11
+ (doc["inner"] || []).each { |child| walk(child, &blk) }
12
+ end
13
+
14
+ def struct doc, name
15
+ walk doc do |node|
16
+ if node["kind"] == "RecordDecl" && node["name"] == name && node["inner"]
17
+ return [name, node["inner"].find_all { |x| x["kind"] == "FieldDecl" }.map { |x|
18
+ x["name"]
19
+ }]
20
+ end
21
+ end
22
+ nil
23
+ end
24
+
25
+ STRUCTS = %w{
26
+ RTypedData
27
+ RBasic
28
+ RObject
29
+ RArray
30
+ RData
31
+ }
32
+
33
+ file "ext/hacks/structs.rb" do
34
+ require "tempfile"
35
+ require "rbconfig"
36
+ require "open3"
37
+ require "json"
38
+
39
+ h_dir = RbConfig::CONFIG["rubyhdrdir"]
40
+ arch_dir = RbConfig::CONFIG["rubyarchhdrdir"]
41
+ file = Tempfile.new('c_file')
42
+
43
+ begin
44
+ file.write "#include <ruby.h>"
45
+ file.close
46
+
47
+ cmd = "clang -I#{h_dir} -I#{arch_dir} -xc -Xclang -ast-dump=json -fsyntax-only #{file.path}"
48
+ stdout_and_stderr, status = Open3.capture2e(cmd)
49
+ doc = JSON.load stdout_and_stderr
50
+
51
+ require "pp"
52
+ structs = STRUCTS.map { |name| struct doc, name }.pretty_inspect
53
+
54
+ File.open("ext/hacks/structs.rb", "w") do |f|
55
+ f.write "module Hacks\n STRUCTS = #{structs}\nend"
56
+ end
57
+ ensure
58
+ #file.unlink # deletes the temp file
59
+ end
60
+ end
@@ -0,0 +1,46 @@
1
+ # Only used at gem installation time
2
+ module Hacks
3
+ CONSTANTS = %w{
4
+ RUBY_T_NONE
5
+
6
+ RUBY_T_OBJECT
7
+ RUBY_T_CLASS
8
+ RUBY_T_MODULE
9
+ RUBY_T_FLOAT
10
+ RUBY_T_STRING
11
+ RUBY_T_REGEXP
12
+ RUBY_T_ARRAY
13
+ RUBY_T_HASH
14
+ RUBY_T_STRUCT
15
+ RUBY_T_BIGNUM
16
+ RUBY_T_FILE
17
+ RUBY_T_DATA
18
+ RUBY_T_MATCH
19
+ RUBY_T_COMPLEX
20
+ RUBY_T_RATIONAL
21
+
22
+ RUBY_T_NIL
23
+ RUBY_T_TRUE
24
+ RUBY_T_FALSE
25
+ RUBY_T_SYMBOL
26
+ RUBY_T_FIXNUM
27
+ RUBY_T_UNDEF
28
+
29
+ RUBY_T_IMEMO
30
+ RUBY_T_NODE
31
+ RUBY_T_ICLASS
32
+ RUBY_T_ZOMBIE
33
+ RUBY_T_MOVED
34
+
35
+ RUBY_T_MASK
36
+ RUBY_Qfalse
37
+ RUBY_Qnil
38
+ RUBY_Qtrue
39
+ RUBY_Qundef
40
+ RUBY_IMMEDIATE_MASK
41
+ RUBY_FIXNUM_FLAG
42
+ RUBY_FLONUM_MASK
43
+ RUBY_FLONUM_FLAG
44
+ RUBY_SYMBOL_FLAG
45
+ }
46
+ end
data/ext/hacks/extconf.rb CHANGED
@@ -1,51 +1,10 @@
1
1
  require "mkmf"
2
2
  require "erb"
3
3
 
4
- constants = %w{
5
- RUBY_T_NONE
4
+ require File.join File.dirname(__FILE__), "constants.rb"
5
+ require File.join File.dirname(__FILE__), "structs.rb"
6
6
 
7
- RUBY_T_OBJECT
8
- RUBY_T_CLASS
9
- RUBY_T_MODULE
10
- RUBY_T_FLOAT
11
- RUBY_T_STRING
12
- RUBY_T_REGEXP
13
- RUBY_T_ARRAY
14
- RUBY_T_HASH
15
- RUBY_T_STRUCT
16
- RUBY_T_BIGNUM
17
- RUBY_T_FILE
18
- RUBY_T_DATA
19
- RUBY_T_MATCH
20
- RUBY_T_COMPLEX
21
- RUBY_T_RATIONAL
22
-
23
- RUBY_T_NIL
24
- RUBY_T_TRUE
25
- RUBY_T_FALSE
26
- RUBY_T_SYMBOL
27
- RUBY_T_FIXNUM
28
- RUBY_T_UNDEF
29
-
30
- RUBY_T_IMEMO
31
- RUBY_T_NODE
32
- RUBY_T_ICLASS
33
- RUBY_T_ZOMBIE
34
- RUBY_T_MOVED
35
-
36
- RUBY_T_MASK
37
- RUBY_Qfalse
38
- RUBY_Qnil
39
- RUBY_Qtrue
40
- RUBY_Qundef
41
- RUBY_IMMEDIATE_MASK
42
- RUBY_FIXNUM_FLAG
43
- RUBY_FLONUM_MASK
44
- RUBY_FLONUM_FLAG
45
- RUBY_SYMBOL_FLAG
46
- }
47
-
48
- def make_c constants
7
+ def make_c constants, structs
49
8
  erb_file = File.join File.dirname(__FILE__), "hacks.c.erb"
50
9
  erb = ERB.new(File.binread(erb_file), trim_mode: "-")
51
10
  c = erb.result(binding)
@@ -53,6 +12,6 @@ def make_c constants
53
12
  File.binwrite c_file, c
54
13
  end
55
14
 
56
- make_c constants.find_all { have_const(_1) }.map { [_1.sub(/^RUBY_/, ''), _1] }
15
+ make_c Hacks::CONSTANTS.find_all { have_const(_1) }.map { [_1.sub(/^RUBY_/, ''), _1] }, Hacks::STRUCTS
57
16
 
58
17
  create_makefile "hacks"
@@ -1,11 +1,36 @@
1
1
  #include <ruby.h>
2
2
 
3
+ static VALUE
4
+ hacks_rb_intern_str(VALUE mod, VALUE x)
5
+ {
6
+ return rb_intern_str(x);
7
+ }
8
+
9
+ static VALUE
10
+ hacks_rb_gc_writebarrier(VALUE mod, VALUE x, VALUE y)
11
+ {
12
+ rb_gc_writebarrier(x, y);
13
+ return Qtrue;
14
+ }
15
+
16
+ static VALUE
17
+ hacks_rb_obj_class(VALUE mod, VALUE x)
18
+ {
19
+ return rb_obj_class(x);
20
+ }
21
+
3
22
  static VALUE
4
23
  hacks_rb_type(VALUE mod, VALUE x)
5
24
  {
6
25
  return INT2NUM(rb_type(x));
7
26
  }
8
27
 
28
+ static VALUE
29
+ hacks_rb_id2sym(VALUE mod, VALUE x)
30
+ {
31
+ return rb_id2sym((ID)NUM2INT(x));
32
+ }
33
+
9
34
  void Init_hacks(void)
10
35
  {
11
36
  VALUE rb_mHacks = rb_define_module("Hacks");
@@ -13,5 +38,26 @@ void Init_hacks(void)
13
38
  rb_define_const(rb_mHacks, "<%= ruby_name %>", INT2NUM(<%= c_name %>));
14
39
  <%- end -%>
15
40
 
41
+ VALUE offsets = rb_hash_new();
42
+ VALUE tmp;
43
+ VALUE tmp2;
44
+ <%- structs.each do |struct_name, members| -%>
45
+ tmp = rb_hash_new();
46
+ <%- members.each do |member_name| -%>
47
+ tmp2 = rb_ary_new();
48
+ // Offset
49
+ rb_ary_store(tmp2, 0, INT2NUM(offsetof(struct <%= struct_name %>, <%= member_name %>)));
50
+ // Size
51
+ rb_ary_store(tmp2, 1, INT2NUM(sizeof(((struct <%= struct_name %> *)0)-><%= member_name %>)));
52
+ rb_hash_aset(tmp, rb_str_new2("<%= member_name %>"), tmp2);
53
+ <%- end -%>
54
+ rb_hash_aset(offsets, rb_str_new2("<%= struct_name %>"), tmp);
55
+ <%- end -%>
56
+ rb_define_const(rb_mHacks, "STRUCTS", offsets);
57
+
16
58
  rb_define_singleton_method(rb_mHacks, "rb_type", hacks_rb_type, 1);
59
+ rb_define_singleton_method(rb_mHacks, "rb_id2sym", hacks_rb_id2sym, 1);
60
+ rb_define_singleton_method(rb_mHacks, "rb_obj_class", hacks_rb_obj_class, 1);
61
+ rb_define_singleton_method(rb_mHacks, "rb_gc_writebarrier", hacks_rb_gc_writebarrier, 2);
62
+ rb_define_singleton_method(rb_mHacks, "rb_intern_str", hacks_rb_intern_str, 1);
17
63
  }
@@ -0,0 +1,8 @@
1
+ module Hacks
2
+ STRUCTS = [["RTypedData", ["basic", "type", "typed_flag", "data"]],
3
+ ["RBasic", ["flags", "klass"]],
4
+ ["RObject", ["basic", "as"]],
5
+ ["RArray", ["basic", "as"]],
6
+ ["RData", ["basic", "dmark", "dfree", "data"]]]
7
+
8
+ end
data/hacks.gemspec CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  Gem::Specification.new do |s|
4
4
  s.name = "hacks"
5
- s.version = "0.0.1"
5
+ s.version = "0.0.3"
6
6
  s.summary = "Ruby C internals exposed as Ruby"
7
7
  s.description = "These are some hacks I use. This gem exposes some Ruby C internals as Ruby functions and constants"
8
8
  s.authors = ["Aaron Patterson"]
data/lib/hacks.rb ADDED
@@ -0,0 +1,9 @@
1
+ require "hacks.so"
2
+
3
+ module Hacks
4
+ BASIC_TYPE_LUT = Hash[constants.grep(/^T_/).map { [const_get(_1), _1] }]
5
+
6
+ def self.basic_type obj
7
+ BASIC_TYPE_LUT[rb_type(obj)]
8
+ end
9
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hacks
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-27 00:00:00.000000000 Z
11
+ date: 2023-03-15 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -50,9 +50,12 @@ files:
50
50
  - LICENSE
51
51
  - README.md
52
52
  - Rakefile
53
+ - ext/hacks/constants.rb
53
54
  - ext/hacks/extconf.rb
54
55
  - ext/hacks/hacks.c.erb
56
+ - ext/hacks/structs.rb
55
57
  - hacks.gemspec
58
+ - lib/hacks.rb
56
59
  homepage: https://github.com/tenderlove/hacks
57
60
  licenses:
58
61
  - Apache-2.0
@@ -72,7 +75,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
72
75
  - !ruby/object:Gem::Version
73
76
  version: '0'
74
77
  requirements: []
75
- rubygems_version: 3.4.1
78
+ rubygems_version: 3.5.0.dev
76
79
  signing_key:
77
80
  specification_version: 4
78
81
  summary: Ruby C internals exposed as Ruby