sq_mini_racer 0.2.5.0.2 → 0.3.1.0.0

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.
@@ -0,0 +1,8 @@
1
+ require 'mkmf'
2
+
3
+ extension_name = 'sq_mini_racer_loader'
4
+ dir_config extension_name
5
+
6
+ $CPPFLAGS += " -fvisibility=hidden "
7
+
8
+ create_makefile extension_name
@@ -4,7 +4,11 @@
4
4
  #include <stdint.h>
5
5
  #include <stdlib.h>
6
6
 
7
- void Init_prv_ext_loader(void);
7
+ // Load a Ruby extension like Ruby does, only with flags that:
8
+ // a) hide symbols from other extensions (RTLD_LOCAL)
9
+ // b) bind symbols tightly (RTLD_DEEPBIND, when available)
10
+
11
+ void Init_sq_mini_racer_loader(void);
8
12
 
9
13
  static void *_dln_load(const char *file);
10
14
 
@@ -24,6 +28,7 @@ static VALUE _load_shared_lib(VALUE self, volatile VALUE fname)
24
28
  return handle ? Qtrue : Qfalse;
25
29
  }
26
30
 
31
+ // adapted from Ruby's dln.c
27
32
  #define INIT_FUNC_PREFIX ((char[]) {'I', 'n', 'i', 't', '_'})
28
33
  #define INIT_FUNCNAME(buf, file) do { \
29
34
  const char *base = (file); \
@@ -36,6 +41,7 @@ static VALUE _load_shared_lib(VALUE self, volatile VALUE fname)
36
41
  *(buf) = tmp; \
37
42
  } while(0)
38
43
 
44
+ // adapted from Ruby's dln.c
39
45
  static size_t _init_funcname(const char **file)
40
46
  {
41
47
  const char *p = *file,
@@ -55,6 +61,7 @@ static size_t _init_funcname(const char **file)
55
61
  return (uintptr_t) ((dot ? dot : p) - base);
56
62
  }
57
63
 
64
+ // adapted from Ruby's dln.c
58
65
  static void *_dln_load(const char *file)
59
66
  {
60
67
  char *buf;
@@ -108,9 +115,21 @@ failed:
108
115
  rb_raise(rb_eLoadError, "%s", error);
109
116
  }
110
117
 
111
- void Init_prv_ext_loader()
118
+ __attribute__((visibility("default"))) void Init_sq_mini_racer_loader()
112
119
  {
113
- VALUE mSqreen = rb_define_module("Sqreen");
114
- VALUE mPrvExtLoader = rb_define_module_under(mSqreen, "PrvExtLoader");
115
- rb_define_singleton_method(mPrvExtLoader, "load", _load_shared_lib, 1);
120
+ ID sqreen_id = rb_intern("Sqreen");
121
+ VALUE mSqreen;
122
+ if (rb_const_defined(rb_cObject, sqreen_id)) {
123
+ mSqreen = rb_const_get(rb_cObject, sqreen_id);
124
+ if (TYPE(mSqreen) != T_MODULE) {
125
+ rb_raise(rb_eTypeError, "Sqreen is not a module");
126
+ return;
127
+ }
128
+ } else {
129
+ mSqreen = rb_define_module("Sqreen");
130
+ }
131
+
132
+ VALUE mMiniRacer = rb_define_module_under(mSqreen, "MiniRacer");
133
+ VALUE mLoader = rb_define_module_under(mMiniRacer, "Loader");
134
+ rb_define_singleton_method(mLoader, "load", _load_shared_lib, 1);
116
135
  }
@@ -1,18 +1,18 @@
1
1
  require "sqreen/mini_racer/version"
2
- require "thread"
3
- require "json"
4
- require "prv_ext_loader"
2
+ require "sq_mini_racer_loader"
5
3
  require "pathname"
6
4
 
7
- module Sqreen
8
- name = 'sq_mini_racer_extension.' + RbConfig::CONFIG['DLEXT']
9
- shlib = $LOAD_PATH
10
- .map { |p| (Pathname.new(p) + name) }
11
- .find { |p| p.file? }
5
+ ext_filename = "sq_mini_racer_extension.#{RbConfig::CONFIG['DLEXT']}"
6
+ ext_path = $LOAD_PATH.map { |p| Pathname.new(p) }
7
+ ext_found = ext_path.map { |p| p + ext_filename }.find { |p| p.file? }
8
+
9
+ raise LoadError, "Could not find #{ext_filename} in #{ext_path.map(&:to_s)}" unless ext_found
10
+ Sqreen::MiniRacer::Loader.load(ext_found.to_s)
12
11
 
13
- raise LoadError, "could not find #{name}" unless shlib
14
- PrvExtLoader.load shlib.to_s
12
+ require "thread"
13
+ require "json"
15
14
 
15
+ module Sqreen
16
16
  # rubocop:disable IndentationConsistency
17
17
  module MiniRacer
18
18
 
@@ -141,21 +141,29 @@ module MiniRacer
141
141
  end
142
142
  end
143
143
 
144
- def initialize(options = nil)
144
+ def initialize(max_memory: nil, timeout: nil, isolate: nil, ensure_gc_after_idle: nil, snapshot: nil)
145
145
  options ||= {}
146
146
 
147
- check_init_options!(options)
147
+ check_init_options!(isolate: isolate, snapshot: snapshot, max_memory: max_memory, ensure_gc_after_idle: ensure_gc_after_idle, timeout: timeout)
148
148
 
149
149
  @functions = {}
150
150
  @timeout = nil
151
151
  @max_memory = nil
152
152
  @current_exception = nil
153
- @timeout = options[:timeout]
154
- if options[:max_memory].is_a?(Numeric) && options[:max_memory] > 0
155
- @max_memory = options[:max_memory]
156
- end
153
+ @timeout = timeout
154
+ @max_memory = max_memory
155
+
157
156
  # false signals it should be fetched if requested
158
- @isolate = options[:isolate] || false
157
+ @isolate = isolate || false
158
+
159
+ @ensure_gc_after_idle = ensure_gc_after_idle
160
+
161
+ if @ensure_gc_after_idle
162
+ @last_eval = nil
163
+ @ensure_gc_thread = nil
164
+ @ensure_gc_mutex = Mutex.new
165
+ end
166
+
159
167
  @disposed = false
160
168
 
161
169
  @callback_mutex = Mutex.new
@@ -164,7 +172,7 @@ module MiniRacer
164
172
  @eval_thread = nil
165
173
 
166
174
  # defined in the C class
167
- init_unsafe(options[:isolate], options[:snapshot])
175
+ init_unsafe(isolate, snapshot)
168
176
  end
169
177
 
170
178
  def isolate
@@ -214,6 +222,7 @@ module MiniRacer
214
222
  end
215
223
  ensure
216
224
  @eval_thread = nil
225
+ ensure_gc_thread if @ensure_gc_after_idle
217
226
  end
218
227
 
219
228
  def call(function_name, *arguments)
@@ -227,16 +236,18 @@ module MiniRacer
227
236
  end
228
237
  ensure
229
238
  @eval_thread = nil
239
+ ensure_gc_thread if @ensure_gc_after_idle
230
240
  end
231
241
 
232
242
  def dispose
233
243
  return if @disposed
234
244
  isolate_mutex.synchronize do
245
+ return if @disposed
235
246
  dispose_unsafe
236
- end
237
247
  @disposed = true
238
248
  @isolate = nil # allow it to be garbage collected, if set
239
249
  end
250
+ end
240
251
 
241
252
 
242
253
  def attach(name, callback)
@@ -284,6 +295,38 @@ module MiniRacer
284
295
 
285
296
  private
286
297
 
298
+ def ensure_gc_thread
299
+ @last_eval = Sqreen::MiniRacer.monotime
300
+ @ensure_gc_mutex.synchronize do
301
+ @ensure_gc_thread = nil if !@ensure_gc_thread || !@ensure_gc_thread.alive?
302
+ @ensure_gc_thread ||= Thread.new do
303
+ ensure_gc_after_idle_seconds = @ensure_gc_after_idle / 1000.0
304
+ done = false
305
+ while !done
306
+ now = Sqreen::MiniRacer.monotime
307
+
308
+ if @disposed
309
+ @ensure_gc_thread = nil
310
+ break
311
+ end
312
+
313
+ if !@eval_thread && ensure_gc_after_idle_seconds < now - @last_eval
314
+ @ensure_gc_mutex.synchronize do
315
+ isolate_mutex.synchronize do
316
+ if !@eval_thread
317
+ isolate.low_memory_notification if !@disposed
318
+ @ensure_gc_thread = nil
319
+ done = true
320
+ end
321
+ end
322
+ end
323
+ end
324
+ sleep ensure_gc_after_idle_seconds if !done
325
+ end
326
+ end
327
+ end
328
+ end
329
+
287
330
  def stop_attached
288
331
  @callback_mutex.synchronize{
289
332
  if @callback_running
@@ -324,20 +367,43 @@ module MiniRacer
324
367
 
325
368
  # ensure we do not leak a thread in state
326
369
  t.join
370
+ t = nil
327
371
 
328
372
  rval
329
-
373
+ ensure
374
+ # exceptions need to be handled
375
+ if t && wp
376
+ wp.write("done")
377
+ t.join
378
+ end
379
+ wp.close if wp
380
+ rp.close if rp
330
381
  end
331
382
 
332
- def check_init_options!(options)
333
- assert_option_is_nil_or_a('isolate', options[:isolate], Isolate)
334
- assert_option_is_nil_or_a('snapshot', options[:snapshot], Snapshot)
383
+ def check_init_options!(isolate: nil, snapshot: nil, max_memory: nil,
384
+ ensure_gc_after_idle: nil, timeout: nil)
385
+ assert_option_is_nil_or_a('isolate', isolate, Isolate)
386
+ assert_option_is_nil_or_a('snapshot', snapshot, Snapshot)
335
387
 
336
- if options[:isolate] && options[:snapshot]
388
+ assert_numeric_or_nil('max_memory', max_memory, min_value: 10_000)
389
+ assert_numeric_or_nil('ensure_gc_after_idle', ensure_gc_after_idle, min_value: 1)
390
+ assert_numeric_or_nil('timeout', timeout, min_value: 1)
391
+
392
+ if isolate && snapshot
337
393
  raise ArgumentError, 'can only pass one of isolate and snapshot options'
338
394
  end
339
395
  end
340
396
 
397
+ def assert_numeric_or_nil(option_name, object, min_value: nil)
398
+ if object.is_a?(Numeric) && object < min_value
399
+ raise ArgumentError, "#{option_name} must be larger than #{min_value}"
400
+ end
401
+
402
+ if !object.nil? && !object.is_a?(Numeric)
403
+ raise ArgumentError, "#{option_name} must be a number, passed a #{object.inspect}"
404
+ end
405
+ end
406
+
341
407
  def assert_option_is_nil_or_a(option_name, object, klass)
342
408
  unless object.nil? || object.is_a?(klass)
343
409
  raise ArgumentError, "#{option_name} must be a #{klass} object, passed a #{object.inspect}"
@@ -1,7 +1,7 @@
1
1
  module Sqreen
2
2
  module MiniRacer
3
- # part before qualifier is the number of the last upstream release
4
- # since we synced with it
5
- VERSION = "0.2.5.0.2"
3
+ # first three numbers is the upstream version
4
+ # that we last merged with
5
+ VERSION = "0.3.1.0.0"
6
6
  end
7
7
  end
data/mini_racer.gemspec CHANGED
@@ -14,6 +14,12 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/sqreen/mini_racer"
15
15
  spec.license = "MIT"
16
16
 
17
+ spec.metadata = {
18
+ "bug_tracker_uri" => "https://github.com/discourse/mini_racer/issues",
19
+ "changelog_uri" => "https://github.com/discourse/mini_racer/blob/v#{spec.version}/CHANGELOG",
20
+ "documentation_uri" => "https://www.rubydoc.info/gems/mini_racer/#{spec.version}",
21
+ "source_code_uri" => "https://github.com/discourse/mini_racer/tree/v#{spec.version}",
22
+ } if spec.respond_to?(:metadata=)
17
23
 
18
24
  REJECTS = %r{\A((benchmark|test|spec|features|examples)/|bench\.rb|.+\.sh|Jenkinsfile)}
19
25
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(REJECTS) }
@@ -21,13 +27,16 @@ Gem::Specification.new do |spec|
21
27
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
28
  spec.require_paths = ["lib"]
23
29
 
24
- spec.add_development_dependency "rake", "~> 10.0"
25
- spec.add_development_dependency "minitest", "~> 5.0"
26
- spec.add_development_dependency "rake-compiler"
30
+ spec.add_development_dependency "bundler"
31
+ spec.add_development_dependency "rake", ">= 12.3.3"
32
+ spec.add_development_dependency "minitest", "~> 5.0", '< 5.13'
33
+ spec.add_development_dependency 'minitest-junit', '~> 0.2.0'
34
+ spec.add_development_dependency "rake-compiler", '< 1.0.3' # avoid https://github.com/rake-compiler/rake-compiler/commit/0dc23504cb03ed2fb3c506e1bb58af48d3851d1e
35
+ spec.add_development_dependency "m"
27
36
 
28
37
  spec.require_paths = ["lib", "ext"]
29
38
 
30
- spec.extensions = ["ext/mini_racer_extension/extconf.rb", "ext/prv_ext_loader/extconf.rb"]
39
+ spec.extensions = ["ext/mini_racer_loader/extconf.rb", "ext/mini_racer_extension/extconf.rb"]
31
40
 
32
- spec.required_ruby_version = '>= 1.9.3'
41
+ spec.required_ruby_version = '>= 2.0.0'
33
42
  end
data/valgrind.supp ADDED
@@ -0,0 +1,74 @@
1
+ {
2
+ <gc cond>
3
+ Memcheck:Cond
4
+ ...
5
+ fun:gc_*
6
+ ...
7
+ }
8
+ {
9
+ <gc_collect cond>
10
+ Memcheck:Cond
11
+ ...
12
+ fun:garbage_collect_*
13
+ ...
14
+ }
15
+ {
16
+ <rgeng cond>
17
+ Memcheck:Cond
18
+ ...
19
+ fun:rgengc_*
20
+ ...
21
+ }
22
+ {
23
+ <gc value8>
24
+ Memcheck:Value8
25
+ ...
26
+ fun:gc_*
27
+ ...
28
+ }
29
+ {
30
+ <rb_gc cond>
31
+ Memcheck:Cond
32
+ ...
33
+ fun:rb_gc_*
34
+ ...
35
+ }
36
+ {
37
+ <rb_gc value8>
38
+ Memcheck:Value8
39
+ ...
40
+ fun:rb_gc_*
41
+ ...
42
+ }
43
+ {
44
+ <fstr_update_callback cond>
45
+ Memcheck:Cond
46
+ fun:fstr_update_callback
47
+ ...
48
+ }
49
+ {
50
+ <init_stack>
51
+ Memcheck:Addr1
52
+ fun:reserve_stack
53
+ fun:ruby_init_stack
54
+ fun:main
55
+ }
56
+ {
57
+ <unreachable chunk>
58
+ Memcheck:Cond
59
+ ...
60
+ fun:remove_unreachable_chunk
61
+ ...
62
+ }
63
+ {
64
+ <fstring_existing_str>
65
+ Memcheck:Cond
66
+ fun:fstring_existing_str
67
+ ...
68
+ }
69
+ {
70
+ <dsymbol_check>
71
+ Memcheck:Cond
72
+ fun:dsymbol_check
73
+ ...
74
+ }
metadata CHANGED
@@ -1,29 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sq_mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5.0.2
4
+ version: 0.3.1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-16 00:00:00.000000000 Z
11
+ date: 2020-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
16
30
  requirements:
17
- - - "~>"
31
+ - - ">="
18
32
  - !ruby/object:Gem::Version
19
- version: '10.0'
33
+ version: 12.3.3
20
34
  type: :development
21
35
  prerelease: false
22
36
  version_requirements: !ruby/object:Gem::Requirement
23
37
  requirements:
24
- - - "~>"
38
+ - - ">="
25
39
  - !ruby/object:Gem::Version
26
- version: '10.0'
40
+ version: 12.3.3
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: minitest
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -31,6 +45,9 @@ dependencies:
31
45
  - - "~>"
32
46
  - !ruby/object:Gem::Version
33
47
  version: '5.0'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '5.13'
34
51
  type: :development
35
52
  prerelease: false
36
53
  version_requirements: !ruby/object:Gem::Requirement
@@ -38,8 +55,39 @@ dependencies:
38
55
  - - "~>"
39
56
  - !ruby/object:Gem::Version
40
57
  version: '5.0'
58
+ - - "<"
59
+ - !ruby/object:Gem::Version
60
+ version: '5.13'
61
+ - !ruby/object:Gem::Dependency
62
+ name: minitest-junit
63
+ requirement: !ruby/object:Gem::Requirement
64
+ requirements:
65
+ - - "~>"
66
+ - !ruby/object:Gem::Version
67
+ version: 0.2.0
68
+ type: :development
69
+ prerelease: false
70
+ version_requirements: !ruby/object:Gem::Requirement
71
+ requirements:
72
+ - - "~>"
73
+ - !ruby/object:Gem::Version
74
+ version: 0.2.0
41
75
  - !ruby/object:Gem::Dependency
42
76
  name: rake-compiler
77
+ requirement: !ruby/object:Gem::Requirement
78
+ requirements:
79
+ - - "<"
80
+ - !ruby/object:Gem::Version
81
+ version: 1.0.3
82
+ type: :development
83
+ prerelease: false
84
+ version_requirements: !ruby/object:Gem::Requirement
85
+ requirements:
86
+ - - "<"
87
+ - !ruby/object:Gem::Version
88
+ version: 1.0.3
89
+ - !ruby/object:Gem::Dependency
90
+ name: m
43
91
  requirement: !ruby/object:Gem::Requirement
44
92
  requirements:
45
93
  - - ">="
@@ -57,13 +105,12 @@ email:
57
105
  - sam.saffron@gmail.com
58
106
  executables: []
59
107
  extensions:
108
+ - ext/mini_racer_loader/extconf.rb
60
109
  - ext/mini_racer_extension/extconf.rb
61
- - ext/prv_ext_loader/extconf.rb
62
110
  extra_rdoc_files: []
63
111
  files:
64
112
  - ".dockerignore"
65
113
  - ".gitignore"
66
- - ".travis.yml"
67
114
  - CHANGELOG
68
115
  - CODE_OF_CONDUCT.md
69
116
  - Dockerfile
@@ -79,17 +126,22 @@ files:
79
126
  - ext/mini_racer_extension/extconf.rb
80
127
  - ext/mini_racer_extension/mini_racer_extension.cc
81
128
  - ext/mini_racer_extension/simdutf8check.h
82
- - ext/prv_ext_loader/extconf.rb
83
- - ext/prv_ext_loader/prv_ext_loader.c
129
+ - ext/mini_racer_loader/extconf.rb
130
+ - ext/mini_racer_loader/mini_racer_loader.c
84
131
  - lib/sq_mini_racer.rb
85
132
  - lib/sqreen/mini_racer.rb
86
133
  - lib/sqreen/mini_racer/version.rb
87
134
  - mini_racer.gemspec
135
+ - valgrind.supp
88
136
  homepage: https://github.com/sqreen/mini_racer
89
137
  licenses:
90
138
  - MIT
91
- metadata: {}
92
- post_install_message:
139
+ metadata:
140
+ bug_tracker_uri: https://github.com/discourse/mini_racer/issues
141
+ changelog_uri: https://github.com/discourse/mini_racer/blob/v0.3.1.0.0/CHANGELOG
142
+ documentation_uri: https://www.rubydoc.info/gems/mini_racer/0.3.1.0.0
143
+ source_code_uri: https://github.com/discourse/mini_racer/tree/v0.3.1.0.0
144
+ post_install_message:
93
145
  rdoc_options: []
94
146
  require_paths:
95
147
  - lib
@@ -98,15 +150,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
98
150
  requirements:
99
151
  - - ">="
100
152
  - !ruby/object:Gem::Version
101
- version: 1.9.3
153
+ version: 2.0.0
102
154
  required_rubygems_version: !ruby/object:Gem::Requirement
103
155
  requirements:
104
156
  - - ">="
105
157
  - !ruby/object:Gem::Version
106
158
  version: '0'
107
159
  requirements: []
108
- rubygems_version: 3.1.3
109
- signing_key:
160
+ rubygems_version: 3.1.2
161
+ signing_key:
110
162
  specification_version: 4
111
163
  summary: Minimal embedded v8 for Ruby
112
164
  test_files: []