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 +4 -4
- data/Rakefile +57 -1
- data/ext/hacks/constants.rb +46 -0
- data/ext/hacks/extconf.rb +4 -45
- data/ext/hacks/hacks.c.erb +46 -0
- data/ext/hacks/structs.rb +8 -0
- data/hacks.gemspec +1 -1
- data/lib/hacks.rb +9 -0
- metadata +6 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 9d864adfb10ffe7141efe44a825a6691a50564bb5762a81d0ab970afe264eb34
|
4
|
+
data.tar.gz: a653799f9f87b99e9d83c893aa793da7f8152dbddabc9be987be45faac2cb527
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
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
|
-
|
5
|
-
|
4
|
+
require File.join File.dirname(__FILE__), "constants.rb"
|
5
|
+
require File.join File.dirname(__FILE__), "structs.rb"
|
6
6
|
|
7
|
-
|
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
|
15
|
+
make_c Hacks::CONSTANTS.find_all { have_const(_1) }.map { [_1.sub(/^RUBY_/, ''), _1] }, Hacks::STRUCTS
|
57
16
|
|
58
17
|
create_makefile "hacks"
|
data/ext/hacks/hacks.c.erb
CHANGED
@@ -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
|
}
|
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.
|
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
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.
|
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:
|
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.
|
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
|