sq_mini_racer 0.2.4.sqreen2 → 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
  }
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'sqreen/mini_racer'
@@ -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? }
12
8
 
13
- raise LoadError, "could not find #{name}" unless shlib
14
- PrvExtLoader.load shlib.to_s
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)
11
+
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
@@ -178,6 +186,28 @@ module MiniRacer
178
186
  eval(File.read(filename))
179
187
  end
180
188
 
189
+ def write_heap_snapshot(file_or_io)
190
+ f = nil
191
+ implicit = false
192
+
193
+
194
+ if String === file_or_io
195
+ f = File.open(file_or_io, "w")
196
+ implicit = true
197
+ else
198
+ f = file_or_io
199
+ end
200
+
201
+ if !(File === f)
202
+ raise ArgumentError("file_or_io")
203
+ end
204
+
205
+ write_heap_snapshot_unsafe(f)
206
+
207
+ ensure
208
+ f.close if implicit
209
+ end
210
+
181
211
  def eval(str, options=nil)
182
212
  raise(ContextDisposedError, 'attempted to call eval on a disposed context!') if @disposed
183
213
 
@@ -192,6 +222,7 @@ module MiniRacer
192
222
  end
193
223
  ensure
194
224
  @eval_thread = nil
225
+ ensure_gc_thread if @ensure_gc_after_idle
195
226
  end
196
227
 
197
228
  def call(function_name, *arguments)
@@ -205,16 +236,18 @@ module MiniRacer
205
236
  end
206
237
  ensure
207
238
  @eval_thread = nil
239
+ ensure_gc_thread if @ensure_gc_after_idle
208
240
  end
209
241
 
210
242
  def dispose
211
243
  return if @disposed
212
244
  isolate_mutex.synchronize do
245
+ return if @disposed
213
246
  dispose_unsafe
214
- end
215
247
  @disposed = true
216
248
  @isolate = nil # allow it to be garbage collected, if set
217
249
  end
250
+ end
218
251
 
219
252
 
220
253
  def attach(name, callback)
@@ -262,6 +295,38 @@ module MiniRacer
262
295
 
263
296
  private
264
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
+
265
330
  def stop_attached
266
331
  @callback_mutex.synchronize{
267
332
  if @callback_running
@@ -302,20 +367,43 @@ module MiniRacer
302
367
 
303
368
  # ensure we do not leak a thread in state
304
369
  t.join
370
+ t = nil
305
371
 
306
372
  rval
307
-
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
308
381
  end
309
382
 
310
- def check_init_options!(options)
311
- assert_option_is_nil_or_a('isolate', options[:isolate], Isolate)
312
- 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)
387
+
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)
313
391
 
314
- if options[:isolate] && options[:snapshot]
392
+ if isolate && snapshot
315
393
  raise ArgumentError, 'can only pass one of isolate and snapshot options'
316
394
  end
317
395
  end
318
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
+
319
407
  def assert_option_is_nil_or_a(option_name, object, klass)
320
408
  unless object.nil? || object.is_a?(klass)
321
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.4.sqreen2"
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
@@ -14,21 +14,29 @@ Gem::Specification.new do |spec|
14
14
  spec.homepage = "https://github.com/sqreen/mini_racer"
15
15
  spec.license = "MIT"
16
16
 
17
-
18
- REJECTS = %r{\A((benchmark|test|spec|features)/|bench\.rb|.+\.sh|Jenkinsfile)}
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=)
23
+
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) }
20
26
  spec.bindir = "exe"
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 "bundler", "~> 1.12"
25
- spec.add_development_dependency "rake", "~> 10.0"
26
- spec.add_development_dependency "minitest", "~> 5.0"
27
- 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"
28
36
 
29
37
  spec.require_paths = ["lib", "ext"]
30
38
 
31
- 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"]
32
40
 
33
- spec.required_ruby_version = '>= 1.9.3'
41
+ spec.required_ruby_version = '>= 2.0.0'
34
42
  end
@@ -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,43 +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.4.sqreen2
4
+ version: 0.3.1.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Saffron
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-01-16 00:00:00.000000000 Z
11
+ date: 2020-11-02 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - ">="
18
18
  - !ruby/object:Gem::Version
19
- version: '1.12'
19
+ version: '0'
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - ">="
25
25
  - !ruby/object:Gem::Version
26
- version: '1.12'
26
+ version: '0'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - "~>"
31
+ - - ">="
32
32
  - !ruby/object:Gem::Version
33
- version: '10.0'
33
+ version: 12.3.3
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - "~>"
38
+ - - ">="
39
39
  - !ruby/object:Gem::Version
40
- version: '10.0'
40
+ version: 12.3.3
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: minitest
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -45,6 +45,9 @@ dependencies:
45
45
  - - "~>"
46
46
  - !ruby/object:Gem::Version
47
47
  version: '5.0'
48
+ - - "<"
49
+ - !ruby/object:Gem::Version
50
+ version: '5.13'
48
51
  type: :development
49
52
  prerelease: false
50
53
  version_requirements: !ruby/object:Gem::Requirement
@@ -52,8 +55,39 @@ dependencies:
52
55
  - - "~>"
53
56
  - !ruby/object:Gem::Version
54
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
55
75
  - !ruby/object:Gem::Dependency
56
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
57
91
  requirement: !ruby/object:Gem::Requirement
58
92
  requirements:
59
93
  - - ">="
@@ -71,33 +105,42 @@ email:
71
105
  - sam.saffron@gmail.com
72
106
  executables: []
73
107
  extensions:
108
+ - ext/mini_racer_loader/extconf.rb
74
109
  - ext/mini_racer_extension/extconf.rb
75
- - ext/prv_ext_loader/extconf.rb
76
110
  extra_rdoc_files: []
77
111
  files:
112
+ - ".dockerignore"
78
113
  - ".gitignore"
79
- - ".travis.yml"
80
114
  - CHANGELOG
81
115
  - CODE_OF_CONDUCT.md
116
+ - Dockerfile
82
117
  - Gemfile
83
118
  - LICENSE.txt
84
119
  - README.md
85
120
  - Rakefile
121
+ - azure-pipelines.yml
122
+ - azure-template.yml
86
123
  - bin/console
87
124
  - bin/setup
88
125
  - ext/mini_racer_extension/compat.hpp
89
126
  - ext/mini_racer_extension/extconf.rb
90
127
  - ext/mini_racer_extension/mini_racer_extension.cc
91
128
  - ext/mini_racer_extension/simdutf8check.h
92
- - ext/prv_ext_loader/extconf.rb
93
- - ext/prv_ext_loader/prv_ext_loader.c
129
+ - ext/mini_racer_loader/extconf.rb
130
+ - ext/mini_racer_loader/mini_racer_loader.c
131
+ - lib/sq_mini_racer.rb
94
132
  - lib/sqreen/mini_racer.rb
95
133
  - lib/sqreen/mini_racer/version.rb
96
134
  - mini_racer.gemspec
135
+ - valgrind.supp
97
136
  homepage: https://github.com/sqreen/mini_racer
98
137
  licenses:
99
138
  - MIT
100
- metadata: {}
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
101
144
  post_install_message:
102
145
  rdoc_options: []
103
146
  require_paths:
@@ -107,15 +150,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
107
150
  requirements:
108
151
  - - ">="
109
152
  - !ruby/object:Gem::Version
110
- version: 1.9.3
153
+ version: 2.0.0
111
154
  required_rubygems_version: !ruby/object:Gem::Requirement
112
155
  requirements:
113
- - - ">"
156
+ - - ">="
114
157
  - !ruby/object:Gem::Version
115
- version: 1.3.1
158
+ version: '0'
116
159
  requirements: []
117
- rubyforge_project:
118
- rubygems_version: 2.7.7
160
+ rubygems_version: 3.1.2
119
161
  signing_key:
120
162
  specification_version: 4
121
163
  summary: Minimal embedded v8 for Ruby