hacks 0.0.1 → 0.0.2

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: 16f90c56986bf11fcdd769d072e31c2e9a26e7f94279ed86bcf3b4f78363688c
4
+ data.tar.gz: ab237d83bd1a90627c04f55f2751f8f6be9bc0ffe39c917cb25b1a4643b6712e
5
5
  SHA512:
6
- metadata.gz: cb87833249d0fae12c00e87c9d9b2321b7c3ec9404960176d1b7fc2f2fb2f33ed6259c0a11bca8fc26a218f6a8112e8d7a0aee809908526598b09dcaa84a4374
7
- data.tar.gz: 410ab0b742089dedbc90c7cd9f3e359debb9e3f150502eed99905f90d94b04ec8429b1b075c46e7a93da42b07ac1e9a288fac672b0dd01ef664bdb447caa0173
6
+ metadata.gz: eb63ecb06db50c6146cfb69328d60fbe1e74f24affd8ddf448c7158a09a9bd86ad078fd7a8360c0233105f0a16a060b38a129b4c16c3d98db0a4179a9efd5fca
7
+ data.tar.gz: 05c35d336f2264c79304651d5e911589fbed8d960210a2480ecbd5ae6c27b7660a04cee55a214e8c862374db81a669641dafe3ebcf226ae83b9f03dcf0fd6144
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"
@@ -13,5 +13,22 @@ void Init_hacks(void)
13
13
  rb_define_const(rb_mHacks, "<%= ruby_name %>", INT2NUM(<%= c_name %>));
14
14
  <%- end -%>
15
15
 
16
+ VALUE offsets = rb_hash_new();
17
+ VALUE tmp;
18
+ VALUE tmp2;
19
+ <%- structs.each do |struct_name, members| -%>
20
+ tmp = rb_hash_new();
21
+ <%- members.each do |member_name| -%>
22
+ tmp2 = rb_ary_new();
23
+ // Offset
24
+ rb_ary_store(tmp2, 0, INT2NUM(offsetof(struct <%= struct_name %>, <%= member_name %>)));
25
+ // Size
26
+ rb_ary_store(tmp2, 1, INT2NUM(sizeof(((struct <%= struct_name %> *)0)-><%= member_name %>)));
27
+ rb_hash_aset(tmp, rb_str_new2("<%= member_name %>"), tmp2);
28
+ <%- end -%>
29
+ rb_hash_aset(offsets, rb_str_new2("<%= struct_name %>"), tmp);
30
+ <%- end -%>
31
+ rb_define_const(rb_mHacks, "STRUCTS", offsets);
32
+
16
33
  rb_define_singleton_method(rb_mHacks, "rb_type", hacks_rb_type, 1);
17
34
  }
@@ -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.2"
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.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Aaron Patterson
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-12-27 00:00:00.000000000 Z
11
+ date: 2023-02-06 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -50,14 +50,17 @@ 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
59
62
  metadata: {}
60
- post_install_message:
63
+ post_install_message:
61
64
  rdoc_options: []
62
65
  require_paths:
63
66
  - lib
@@ -72,8 +75,8 @@ 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
76
- signing_key:
78
+ rubygems_version: 3.0.3.1
79
+ signing_key:
77
80
  specification_version: 4
78
81
  summary: Ruby C internals exposed as Ruby
79
82
  test_files: []