jit_buffer 1.0.1 → 1.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +0 -3
- data/jit_buffer.gemspec +0 -2
- data/lib/jit_buffer.rb +46 -8
- data/test/jit_buffer_test.rb +10 -21
- metadata +7 -24
- data/ext/jit_buffer/extconf.rb +0 -10
- data/ext/jit_buffer/jit_buffer.c +0 -59
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4be349fa4c465e35b8ef2bd1af1c80d26591146805978803b77ce24487c10724
|
4
|
+
data.tar.gz: 175b24a10629507a105dd34670c1eae51537ceccc2eae60c3fc907a9c16ffb33
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 23302857f3b5646d1c403cfbced18a4f7a98e8af0b93c070a9bc5a0e7c112be3a59bfbfad1952c41991213ad626becc4a36b43ca5040a751518c9d1c23d66be2
|
7
|
+
data.tar.gz: 22690c0bbbc23340c6bbfce56399861834d8960337180f2cc25cfeddee2573887da491aa9e92daf985617b42c30e5e816b2ce38e7564e7bef4c0b42af4331989
|
data/Rakefile
CHANGED
data/jit_buffer.gemspec
CHANGED
@@ -18,10 +18,8 @@ Gem::Specification.new do |spec|
|
|
18
18
|
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
19
|
|
20
20
|
spec.require_paths = ["lib"]
|
21
|
-
spec.extensions = ["ext/jit_buffer/extconf.rb"]
|
22
21
|
|
23
22
|
spec.add_development_dependency "rake", '~> 13.0'
|
24
|
-
spec.add_development_dependency "rake-compiler", '~> 1.1'
|
25
23
|
spec.add_development_dependency "minitest", '~> 5.15'
|
26
24
|
spec.add_dependency "fiddle", '~> 1.1'
|
27
25
|
end
|
data/lib/jit_buffer.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
require "jit_buffer.so"
|
2
1
|
require "fiddle"
|
3
2
|
|
4
3
|
class Fiddle::Function
|
@@ -9,7 +8,7 @@ class Fiddle::Function
|
|
9
8
|
end unless Fiddle::Function.method_defined?(:to_proc)
|
10
9
|
|
11
10
|
class JITBuffer
|
12
|
-
VERSION = '1.0.
|
11
|
+
VERSION = '1.0.2'
|
13
12
|
|
14
13
|
class Exception < StandardError
|
15
14
|
end
|
@@ -23,6 +22,20 @@ class JITBuffer
|
|
23
22
|
module MMAP
|
24
23
|
include Fiddle
|
25
24
|
|
25
|
+
PROT_READ = 0x01
|
26
|
+
PROT_WRITE = 0x02
|
27
|
+
PROT_EXEC = 0x04
|
28
|
+
|
29
|
+
MAP_PRIVATE = 0x02
|
30
|
+
|
31
|
+
if RUBY_PLATFORM =~ /darwin/
|
32
|
+
MAP_ANON = 0x1000
|
33
|
+
MAP_JIT = 0x800
|
34
|
+
else
|
35
|
+
MAP_ANON = 0x20
|
36
|
+
MAP_JIT = 0x0
|
37
|
+
end
|
38
|
+
|
26
39
|
def self.make_function name, args, ret
|
27
40
|
ptr = Handle::DEFAULT[name]
|
28
41
|
func = Function.new ptr, args, ret, name: name
|
@@ -42,17 +55,42 @@ class JITBuffer
|
|
42
55
|
|
43
56
|
make_function "mprotect", [TYPE_VOIDP, TYPE_SIZE_T, TYPE_INT], TYPE_INT
|
44
57
|
|
58
|
+
begin
|
59
|
+
make_function "pthread_jit_write_protect_np", [TYPE_INT], TYPE_VOID
|
60
|
+
make_function "sys_icache_invalidate", [TYPE_VOIDP, -TYPE_INT], TYPE_VOID
|
61
|
+
rescue Fiddle::DLError
|
62
|
+
end
|
63
|
+
|
45
64
|
def self.mmap_buffer size
|
46
65
|
ptr = mmap 0, size, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE | MAP_ANON | MAP_JIT, -1, 0
|
47
66
|
ptr.size = size
|
48
67
|
ptr
|
49
68
|
end
|
69
|
+
|
70
|
+
if respond_to?(:pthread_jit_write_protect_np)
|
71
|
+
# MacOS
|
72
|
+
def self.set_writeable ptr
|
73
|
+
MMAP.pthread_jit_write_protect_np 0
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.set_executable ptr
|
77
|
+
MMAP.pthread_jit_write_protect_np 1
|
78
|
+
MMAP.sys_icache_invalidate ptr, ptr.size
|
79
|
+
end
|
80
|
+
else
|
81
|
+
# Linux
|
82
|
+
def self.set_writeable ptr
|
83
|
+
MMAP.mprotect ptr, ptr.size, PROT_READ | PROT_WRITE
|
84
|
+
end
|
85
|
+
|
86
|
+
def self.set_executable ptr
|
87
|
+
MMAP.mprotect ptr, ptr.size, PROT_READ | PROT_EXEC
|
88
|
+
end
|
89
|
+
end
|
50
90
|
end
|
51
91
|
|
52
92
|
def self.new size
|
53
|
-
|
54
|
-
MMAP.pthread_jit_write_protect_np(true)
|
55
|
-
x
|
93
|
+
super(MMAP.mmap_buffer(size), size)
|
56
94
|
end
|
57
95
|
|
58
96
|
attr_reader :pos
|
@@ -62,6 +100,7 @@ class JITBuffer
|
|
62
100
|
@memory = memory
|
63
101
|
@size = size
|
64
102
|
@pos = 0
|
103
|
+
executable!
|
65
104
|
end
|
66
105
|
|
67
106
|
def putc byte
|
@@ -101,13 +140,12 @@ class JITBuffer
|
|
101
140
|
end
|
102
141
|
|
103
142
|
def executable!
|
104
|
-
MMAP.
|
105
|
-
MMAP.sys_icache_invalidate @memory.to_i, @size
|
143
|
+
MMAP.set_executable @memory.to_i
|
106
144
|
@writeable = false
|
107
145
|
end
|
108
146
|
|
109
147
|
def writeable!
|
110
|
-
MMAP.
|
148
|
+
MMAP.set_writeable @memory.to_i
|
111
149
|
@writeable = true
|
112
150
|
end
|
113
151
|
|
data/test/jit_buffer_test.rb
CHANGED
@@ -46,18 +46,21 @@ class JITBufferTest < Minitest::Test
|
|
46
46
|
|
47
47
|
def test_execute
|
48
48
|
jit = JITBuffer.new 4096
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
49
|
+
|
50
|
+
bytes = [0x48, 0xc7, 0xc0, 0x2b, 0x00, 0x00, 0x00, # x86_64 mov rax, 0x2b
|
51
|
+
0xc3, # x86_64 ret
|
52
|
+
0xeb, 0xf6, # x86 jmp
|
53
|
+
0x80, 0xd2, # ARM movz X11, 0x7b7
|
54
|
+
0x60, 0x05, 0x80, 0xd2, # ARM movz X0, #0x2b
|
55
|
+
0xc0, 0x03, 0x5f, 0xd6] # ARM ret
|
53
56
|
|
54
57
|
jit.writeable!
|
55
58
|
|
56
|
-
jit.write
|
59
|
+
jit.write bytes.pack("C*")
|
57
60
|
|
58
61
|
jit.executable!
|
59
|
-
func = jit.
|
60
|
-
assert_equal
|
62
|
+
func = Fiddle::Function.new(jit.to_i + 8, [], Fiddle::TYPE_INT)
|
63
|
+
assert_equal 43, func.call
|
61
64
|
end
|
62
65
|
|
63
66
|
def test_invalid_write
|
@@ -116,18 +119,4 @@ class JITBufferTest < Minitest::Test
|
|
116
119
|
jit = JITBuffer.new 4096
|
117
120
|
assert jit.to_i
|
118
121
|
end
|
119
|
-
|
120
|
-
# ARM instructions
|
121
|
-
def movz reg, imm
|
122
|
-
insn = 0b0_10_100101_00_0000000000000000_00000
|
123
|
-
insn |= (1 << 31) # 64 bit
|
124
|
-
insn |= (imm << 5) # immediate
|
125
|
-
insn |= reg # reg
|
126
|
-
end
|
127
|
-
|
128
|
-
def ret xn = 30
|
129
|
-
insn = 0b1101011_0_0_10_11111_0000_0_0_00000_00000
|
130
|
-
insn |= (xn << 5)
|
131
|
-
insn
|
132
|
-
end
|
133
122
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: jit_buffer
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.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-04
|
11
|
+
date: 2022-05-04 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -24,20 +24,6 @@ dependencies:
|
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
26
|
version: '13.0'
|
27
|
-
- !ruby/object:Gem::Dependency
|
28
|
-
name: rake-compiler
|
29
|
-
requirement: !ruby/object:Gem::Requirement
|
30
|
-
requirements:
|
31
|
-
- - "~>"
|
32
|
-
- !ruby/object:Gem::Version
|
33
|
-
version: '1.1'
|
34
|
-
type: :development
|
35
|
-
prerelease: false
|
36
|
-
version_requirements: !ruby/object:Gem::Requirement
|
37
|
-
requirements:
|
38
|
-
- - "~>"
|
39
|
-
- !ruby/object:Gem::Version
|
40
|
-
version: '1.1'
|
41
27
|
- !ruby/object:Gem::Dependency
|
42
28
|
name: minitest
|
43
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -70,8 +56,7 @@ description: A JIT Buffer object for Ruby.
|
|
70
56
|
email:
|
71
57
|
- tenderlove@ruby-lang.org
|
72
58
|
executables: []
|
73
|
-
extensions:
|
74
|
-
- ext/jit_buffer/extconf.rb
|
59
|
+
extensions: []
|
75
60
|
extra_rdoc_files: []
|
76
61
|
files:
|
77
62
|
- CODE_OF_CONDUCT.md
|
@@ -79,8 +64,6 @@ files:
|
|
79
64
|
- LICENSE
|
80
65
|
- README.md
|
81
66
|
- Rakefile
|
82
|
-
- ext/jit_buffer/extconf.rb
|
83
|
-
- ext/jit_buffer/jit_buffer.c
|
84
67
|
- jit_buffer.gemspec
|
85
68
|
- lib/jit_buffer.rb
|
86
69
|
- test/helper.rb
|
@@ -89,7 +72,7 @@ homepage: https://github.com/tenderlove/jit_buffer
|
|
89
72
|
licenses:
|
90
73
|
- Apache-2.0
|
91
74
|
metadata: {}
|
92
|
-
post_install_message:
|
75
|
+
post_install_message:
|
93
76
|
rdoc_options: []
|
94
77
|
require_paths:
|
95
78
|
- lib
|
@@ -104,8 +87,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
104
87
|
- !ruby/object:Gem::Version
|
105
88
|
version: '0'
|
106
89
|
requirements: []
|
107
|
-
rubygems_version: 3.
|
108
|
-
signing_key:
|
90
|
+
rubygems_version: 3.0.3.1
|
91
|
+
signing_key:
|
109
92
|
specification_version: 4
|
110
93
|
summary: A JIT Buffer object for Ruby.
|
111
94
|
test_files:
|
data/ext/jit_buffer/extconf.rb
DELETED
data/ext/jit_buffer/jit_buffer.c
DELETED
@@ -1,59 +0,0 @@
|
|
1
|
-
#include <ruby.h>
|
2
|
-
#include <sys/mman.h>
|
3
|
-
#include <mach/vm_prot.h>
|
4
|
-
#include <mach/mach_init.h>
|
5
|
-
#include <pthread.h>
|
6
|
-
|
7
|
-
#if HAVE_SYS_ICACHE_INVALIDATE
|
8
|
-
#include <libkern/OSCacheControl.h>
|
9
|
-
#endif
|
10
|
-
|
11
|
-
#if HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
|
12
|
-
static VALUE
|
13
|
-
rb_pthread_jit_write_protect_np(VALUE mod, VALUE v)
|
14
|
-
{
|
15
|
-
if (RTEST(v)) {
|
16
|
-
pthread_jit_write_protect_np(1);
|
17
|
-
}
|
18
|
-
else {
|
19
|
-
pthread_jit_write_protect_np(0);
|
20
|
-
}
|
21
|
-
|
22
|
-
return Qnil;
|
23
|
-
}
|
24
|
-
#endif
|
25
|
-
|
26
|
-
#if HAVE_SYS_ICACHE_INVALIDATE
|
27
|
-
static VALUE
|
28
|
-
rb_sys_icache_invalidate(VALUE mod, VALUE addr, VALUE len)
|
29
|
-
{
|
30
|
-
sys_icache_invalidate((void *)(NUM2ULONG(addr)), NUM2INT(len));
|
31
|
-
|
32
|
-
return Qnil;
|
33
|
-
}
|
34
|
-
#endif
|
35
|
-
|
36
|
-
void Init_jit_buffer() {
|
37
|
-
VALUE rb_cJITBuffer = rb_define_class("JITBuffer", rb_cObject);
|
38
|
-
VALUE rb_mMMap = rb_define_module_under(rb_cJITBuffer, "MMAP");
|
39
|
-
|
40
|
-
rb_define_const(rb_mMMap, "PROT_READ", INT2NUM(PROT_READ));
|
41
|
-
rb_define_const(rb_mMMap, "PROT_WRITE", INT2NUM(PROT_WRITE));
|
42
|
-
rb_define_const(rb_mMMap, "PROT_EXEC", INT2NUM(PROT_EXEC));
|
43
|
-
rb_define_const(rb_mMMap, "VM_PROT_COPY", INT2NUM(VM_PROT_COPY));
|
44
|
-
rb_define_const(rb_mMMap, "VM_PROT_READ", INT2NUM(VM_PROT_READ));
|
45
|
-
rb_define_const(rb_mMMap, "VM_PROT_EXECUTE", INT2NUM(VM_PROT_EXECUTE));
|
46
|
-
rb_define_const(rb_mMMap, "MAP_PRIVATE", INT2NUM(MAP_PRIVATE));
|
47
|
-
rb_define_const(rb_mMMap, "MAP_ANON", INT2NUM(MAP_ANON));
|
48
|
-
#if HAVE_CONST_MAP_JIT
|
49
|
-
rb_define_const(rb_mMMap, "MAP_JIT", INT2NUM(MAP_JIT));
|
50
|
-
#endif
|
51
|
-
|
52
|
-
#if HAVE_PTHREAD_JIT_WRITE_PROTECT_NP
|
53
|
-
rb_define_module_function(rb_mMMap, "pthread_jit_write_protect_np", rb_pthread_jit_write_protect_np, 1);
|
54
|
-
#endif
|
55
|
-
|
56
|
-
#if HAVE_SYS_ICACHE_INVALIDATE
|
57
|
-
rb_define_module_function(rb_mMMap, "sys_icache_invalidate", rb_sys_icache_invalidate, 2);
|
58
|
-
#endif
|
59
|
-
}
|