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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 17d82de5bc85b557ddb89f5d01b704a6187e008398a1436e373cd32e32cd538b
4
- data.tar.gz: 4f483b84a8aa058607d5f30dfd8bac8bd93d9de3081ba2f76876f08ba354c39b
3
+ metadata.gz: 4be349fa4c465e35b8ef2bd1af1c80d26591146805978803b77ce24487c10724
4
+ data.tar.gz: 175b24a10629507a105dd34670c1eae51537ceccc2eae60c3fc907a9c16ffb33
5
5
  SHA512:
6
- metadata.gz: ee5b84588512a0c383c10c083f7d6df4af529a7d6a681f0cb5f971ef5414d0fbf3bf4a2d543108d6238e9a25452270aeb6c62115fc940f7fcb3a47da2eec4045
7
- data.tar.gz: 5a9d7aefc064cf02b1f2dbc49e859d39daf0a779302f390e462da08972416fe8b335c410ab08c11f0f5bcbfd9b40a51b4a62085714261a96a67b5808163327dd
6
+ metadata.gz: 23302857f3b5646d1c403cfbced18a4f7a98e8af0b93c070a9bc5a0e7c112be3a59bfbfad1952c41991213ad626becc4a36b43ca5040a751518c9d1c23d66be2
7
+ data.tar.gz: 22690c0bbbc23340c6bbfce56399861834d8960337180f2cc25cfeddee2573887da491aa9e92daf985617b42c30e5e816b2ce38e7564e7bef4c0b42af4331989
data/Rakefile CHANGED
@@ -6,6 +6,3 @@ Rake::TestTask.new(:test) do |t|
6
6
  t.verbose = true
7
7
  t.warning = true
8
8
  end
9
-
10
- require 'rake/extensiontask'
11
- Rake::ExtensionTask.new("jit_buffer")
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.1'
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
- x = super(MMAP.mmap_buffer(size), size)
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.pthread_jit_write_protect_np true
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.pthread_jit_write_protect_np false
148
+ MMAP.set_writeable @memory.to_i
111
149
  @writeable = true
112
150
  end
113
151
 
@@ -46,18 +46,21 @@ class JITBufferTest < Minitest::Test
46
46
 
47
47
  def test_execute
48
48
  jit = JITBuffer.new 4096
49
- insns = [
50
- movz(0, 42),
51
- ret
52
- ].pack("L<L<")
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 insns
59
+ jit.write bytes.pack("C*")
57
60
 
58
61
  jit.executable!
59
- func = jit.to_function([], Fiddle::TYPE_INT)
60
- assert_equal 42, func.call
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.1
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-08 00:00:00.000000000 Z
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.4.0.dev
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:
@@ -1,10 +0,0 @@
1
- require 'mkmf'
2
-
3
- raise unless have_header "sys/mman.h"
4
-
5
- have_const 'MAP_JIT', 'sys/mman.h'
6
-
7
- have_func 'pthread_jit_write_protect_np'
8
- have_func 'sys_icache_invalidate'
9
-
10
- create_makefile('jit_buffer')
@@ -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
- }