sq_mini_racer 0.2.4.0.2 → 0.2.5.0.1.beta1

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: eb7be23e127c27a87be5d25075c26ec77ba06f19878e69088827077b6fc5844b
4
- data.tar.gz: cc1a09e6683d40813f8702cd683b0237aa9717e79f3a93c95870367934a06a5f
3
+ metadata.gz: a4deece72e6d02478b4381a59ab9b1988a2fbff6a30e811596183240699fd018
4
+ data.tar.gz: ac83f077c9b56423cd8b8e716d8102bec73050c8a4ae0e525fda931f43ec6762
5
5
  SHA512:
6
- metadata.gz: f854ba80b5702b0620feb0c16126e1b9f4b864a332a1e7b50df15fd4f8af16d49b330cdd296e3fa2b795d7c17857ae66d1705fdf4fd68784288317571120a651
7
- data.tar.gz: 457b7ac2ef3b81a9f5f8d6353cf73c588c12af06af085fcfe456afa29b48ba96f324dc7cae173362a410c3009ae2394d30ea130e5785bcb24741378b79a0f851
6
+ metadata.gz: cad6011c1066ccc51e1c3bfe3064c50e7dbdc6dd04127ce24f855a97f9ba8fd492a5de3b1af54b810b4a112d74f03bcd746c8d95af822a5f9d59e8cd9cdce8a2
7
+ data.tar.gz: f985a398202455acfadd914606306d5469928bfbf69394fd39b5a79b097f81a6994bf4875bb7765d01b4fd2797b00378a5e3d23de4a05b4d3588216e3ac59cc9
data/CHANGELOG CHANGED
@@ -1,3 +1,18 @@
1
+ - 14-05-2019
2
+
3
+ - 0.2.6
4
+
5
+ - FEATURE: add support for write_heap_snapshot which helps you analyze memory
6
+
7
+ - 25-04-2019
8
+
9
+ - 0.2.5
10
+
11
+ - FIX: Compatiblity fixes for V8 7 and above @ignisf
12
+ - FIX: Memory leak in gc_callback @messense
13
+ - IMPROVEMENT: Added example of sourcemap support @ianks
14
+ - URGENT: you will need this release for latest version of libv8 to work
15
+
1
16
  - 02-11-2018
2
17
 
3
18
  - 0.2.4
data/README.md CHANGED
@@ -101,6 +101,27 @@ context.eval('bar()', filename: 'a/bar.js')
101
101
 
102
102
  ```
103
103
 
104
+ ### Fork safety
105
+
106
+ Some Ruby web servers employ forking (for example unicorn or puma in clustered mode). V8 is not fork safe.
107
+ Sadly Ruby does not have support for fork notifications per [#5446](https://bugs.ruby-lang.org/issues/5446).
108
+
109
+ If you want to ensure your application does not leak memory after fork either:
110
+
111
+ 1. Ensure no MiniRacer::Context objects are created in the master process
112
+
113
+ Or
114
+
115
+ 2. Dispose manually of all MiniRacer::Context objects prior to forking
116
+
117
+ ```ruby
118
+ # before fork
119
+
120
+ require 'objspace'
121
+ ObjectSpace.each_object(MiniRacer::Context){|c| c.dispose}
122
+
123
+ # fork here
124
+ ```
104
125
 
105
126
  ### Threadsafe
106
127
 
@@ -350,6 +371,10 @@ Note how the global interpreter lock release leads to 2 threads doing the same w
350
371
 
351
372
  As a rule MiniRacer strives to always support and depend on the latest stable version of libv8.
352
373
 
374
+ ## Source Maps
375
+
376
+ MiniRacer can fully support source maps but must be configured correctly to do so. [Check out this example](./examples/source-map-support/) for a working implementation.
377
+
353
378
  ## Installation
354
379
 
355
380
  Add this line to your application's Gemfile:
data/Rakefile CHANGED
@@ -19,6 +19,22 @@ Rake::ExtensionTask.new('prv_ext_loader', gem)
19
19
 
20
20
  # via http://blog.flavorjon.es/2009/06/easily-valgrind-gdb-your-ruby-c.html
21
21
  namespace :test do
22
+ desc "run test suite with Address Sanitizer"
23
+ task :asan do
24
+ ENV["CONFIGURE_ARGS"] = [ENV["CONFIGURE_ARGS"], '--enable-asan'].compact.join(' ')
25
+ Rake::Task['compile'].invoke
26
+
27
+ asan_path = `ldconfig -N -p |grep libasan | grep -v 32 | sed 's/.* => \\(.*\\)$/\\1/'`.chomp.split("\n")[-1]
28
+
29
+
30
+ cmdline = "env LD_PRELOAD=\"#{asan_path}\" ruby test/test_leak.rb"
31
+ puts cmdline
32
+ system cmdline
33
+
34
+ cmdline = "env LD_PRELOAD=\"#{asan_path}\" rake test"
35
+ puts cmdline
36
+ system cmdline
37
+ end
22
38
  # partial-loads-ok and undef-value-errors necessary to ignore
23
39
  # spurious (and eminently ignorable) warnings from the ruby
24
40
  # interpreter
@@ -55,3 +71,28 @@ namespace :test do
55
71
  end
56
72
  end
57
73
  end
74
+
75
+ desc 'run clang-tidy linter on mini_racer_extension.cc'
76
+ task :lint do
77
+ require 'mkmf'
78
+ require 'libv8'
79
+
80
+ Libv8.configure_makefile
81
+
82
+ conf = RbConfig::CONFIG.merge('hdrdir' => $hdrdir.quote, 'srcdir' => $srcdir.quote,
83
+ 'arch_hdrdir' => $arch_hdrdir.quote,
84
+ 'top_srcdir' => $top_srcdir.quote)
85
+ if $universal and (arch_flag = conf['ARCH_FLAG']) and !arch_flag.empty?
86
+ conf['ARCH_FLAG'] = arch_flag.gsub(/(?:\G|\s)-arch\s+\S+/, '')
87
+ end
88
+
89
+ checks = %W(bugprone-*
90
+ cert-*
91
+ cppcoreguidelines-*
92
+ clang-analyzer-*
93
+ performance-*
94
+ portability-*
95
+ readability-*).join(',')
96
+
97
+ sh RbConfig::expand("clang-tidy -checks='#{checks}' ext/mini_racer_extension/mini_racer_extension.cc -- #$INCFLAGS #$CPPFLAGS", conf)
98
+ end
@@ -26,58 +26,46 @@ def cppflags_add_cpu_extension!
26
26
  end
27
27
 
28
28
  def libv8_gem_name
29
- #return "libv8-solaris" if IS_SOLARIS
30
- #return "libv8-alpine" if IS_LINUX_MUSL
29
+ return "libv8-solaris" if IS_SOLARIS
30
+ return "libv8-alpine" if IS_LINUX_MUSL
31
31
 
32
- 'libv8-node'
32
+ 'libv8'
33
33
  end
34
34
 
35
- def libv8_requirement
36
- '~> 10.22.1.0.beta1'
35
+ def libv8_version
36
+ '7.3.492.27.1'
37
37
  end
38
38
 
39
- def libv8_basename(version)
40
- "#{libv8_gem_name}-#{version}-#{ruby_platform}"
39
+ def libv8_basename
40
+ "#{libv8_gem_name}-#{libv8_version}-#{ruby_platform}"
41
41
  end
42
42
 
43
- def libv8_gemspec(version)
44
- "#{libv8_basename(version)}.gemspec"
43
+ def libv8_gemspec
44
+ "#{libv8_basename}.gemspec"
45
45
  end
46
46
 
47
- def libv8_local_path(path=Gem.path)
48
- name_glob = "#{libv8_gem_name}-*-#{ruby_platform}"
47
+ def libv8_local_path
48
+ puts "looking for #{libv8_gemspec} in installed gems"
49
+ candidates = Gem.path.map { |p| File.join(p, 'specifications', libv8_gemspec) }
50
+ found = candidates.select { |f| File.exist?(f) }.first
49
51
 
50
- puts "looking for #{name_glob} in #{path.inspect}"
51
-
52
- paths = path.map { |p| Dir.glob(File.join(p, 'specifications', name_glob + '.gemspec')) }.flatten
53
-
54
- if paths.empty?
55
- puts "#{name_glob} not found in #{path.inspect}"
56
- return
57
- end
58
-
59
- specs = paths.map { |p| [p, eval(File.read(p))] }
60
- .select { |_, spec| Gem::Requirement.new(libv8_requirement).satisfied_by?(spec.version) }
61
- found_path, found_spec = specs.sort_by { |_, spec| spec.version }.last
62
-
63
- unless found_path && found_spec
64
- puts "not found in specs: no '#{libv8_requirement}' in #{paths.inspect}"
52
+ unless found
53
+ puts "#{libv8_gemspec} not found in installed gems"
65
54
  return
66
55
  end
67
56
 
68
- puts "found in specs: #{found_path}"
57
+ puts "found in installed specs: #{found}"
69
58
 
70
- gemdir = File.basename(found_path, '.gemspec')
71
- dir = File.expand_path(File.join(found_path, '..', '..', 'gems', gemdir))
59
+ dir = File.expand_path(File.join(found, '..', '..', 'gems', libv8_basename))
72
60
 
73
61
  unless Dir.exist?(dir)
74
- puts "not found in gems: #{dir}"
62
+ puts "not found in installed gems: #{dir}"
75
63
  return
76
64
  end
77
65
 
78
- puts "found in gems: #{dir}"
66
+ puts "found in installed gems: #{dir}"
79
67
 
80
- [dir, found_spec]
68
+ dir
81
69
  end
82
70
 
83
71
  def vendor_path
@@ -85,14 +73,25 @@ def vendor_path
85
73
  end
86
74
 
87
75
  def libv8_vendor_path
88
- libv8_local_path([vendor_path])
76
+ puts "looking for #{libv8_basename} in #{vendor_path}"
77
+ path = Dir.glob("#{vendor_path}/#{libv8_basename}").first
78
+
79
+ unless path
80
+ puts "#{libv8_basename} not found in #{vendor_path}"
81
+ return
82
+ end
83
+
84
+ puts "looking for #{libv8_basename}/lib/libv8.rb in #{vendor_path}"
85
+ unless Dir.glob(File.join(vendor_path, libv8_basename, 'lib', 'libv8.rb')).first
86
+ puts "#{libv8_basename}/lib/libv8.rb not found in #{vendor_path}"
87
+ return
88
+ end
89
+
90
+ path
89
91
  end
90
92
 
91
93
  def parse_platform(str)
92
- Gem::Platform.new(str).tap do |p|
93
- p.instance_eval { @version = 'musl' } if str =~ /-musl/ && p.version.nil?
94
- p.instance_eval { @cpu = 'x86_64' } if str =~ /universal.*darwin/
95
- end
94
+ Gem::Platform.new(str).tap { |p| p.instance_eval { @os = 'linux-musl' } if str =~ /musl/ }
96
95
  end
97
96
 
98
97
  def ruby_platform
@@ -114,23 +113,21 @@ def libv8_remote_search
114
113
  json = JSON.parse(body)
115
114
 
116
115
  versions = json.select do |v|
117
- Gem::Requirement.new(libv8_requirement).satisfied_by?(Gem::Version.new(v['number']))
116
+ Gem::Version.new(v['number']) == Gem::Version.new(libv8_version)
118
117
  end
119
118
  abort(<<-ERROR) if versions.empty?
120
- ERROR: could not find #{libv8_gem_name} (requirement #{libv8_requirement}) in rubygems.org
119
+ ERROR: could not find #{libv8_version}
121
120
  ERROR
122
121
 
123
122
  platform_versions = versions.select do |v|
124
- parse_platform(v['platform']) == ruby_platform unless v['platform'] =~ /universal.*darwin/
123
+ parse_platform(v['platform']) == ruby_platform
125
124
  end
126
125
  abort(<<-ERROR) if platform_versions.empty?
127
- ERROR: found gems matching #{libv8_gem_name}:'#{libv8_requirement}', but no binary for #{ruby_platform}
128
- try "gem install #{libv8_gem_name}:'#{libv8_requirement}'" to attempt to build #{libv8_gem_name} from source
126
+ ERROR: found #{libv8_gem_name}-#{libv8_version}, but no binary for #{ruby_platform}
127
+ try "gem install #{libv8_gem_name} -v '#{libv8_version}'" to attempt to build libv8 from source
129
128
  ERROR
130
129
 
131
- puts "found #{libv8_gem_name} for #{ruby_platform} on rubygems: #{platform_versions.map { |v| v['number'] }.join(', ')}"
132
-
133
- platform_versions.sort_by { |v| Gem::Version.new(v['number']) }.last
130
+ platform_versions.first
134
131
  end
135
132
 
136
133
  def libv8_download_uri(name, version, platform)
@@ -142,47 +139,27 @@ def libv8_downloaded_gem(name, version, platform)
142
139
  end
143
140
 
144
141
  def libv8_download(name, version, platform)
145
- FileUtils.mkdir_p(File.join(vendor_path, 'cache'))
142
+ FileUtils.mkdir_p(vendor_path)
146
143
  body = http_get(libv8_download_uri(name, version, platform))
147
- File.open(File.join(vendor_path, 'cache', libv8_downloaded_gem(name, version, platform)), 'wb') { |f| f.write(body) }
148
- end
149
-
150
- def libv8_install!
151
- cmd = "gem install #{libv8_gem_name} --version '#{libv8_requirement}' --install-dir '#{vendor_path}'"
152
- puts "installing #{libv8_gem_name} using `#{cmd}`"
153
- rc = system(cmd)
154
-
155
- abort(<<-ERROR) unless rc
156
- ERROR: could not install #{libv8_gem_name}:#{libv8_requirement}
157
- try "gem install #{libv8_gem_name} -v '#{libv8_requirement}'" to attempt to build libv8 from source
158
- ERROR
159
-
160
- libv8_local_path([vendor_path])
144
+ File.open(File.join(vendor_path, libv8_downloaded_gem(name, version, platform)), 'wb') { |f| f.write(body) }
161
145
  end
162
146
 
163
147
  def libv8_vendor!
164
- return libv8_install! if Gem::VERSION < '2.0'
165
-
166
148
  version = libv8_remote_search
167
149
 
168
150
  puts "downloading #{libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform'])} to #{vendor_path}"
169
151
  libv8_download(libv8_gem_name, version['number'], version['platform'])
170
152
 
171
- package = Gem::Package.new(File.join(vendor_path, 'cache', libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform'])))
172
- package.extract_files(File.join(vendor_path, 'gems', File.basename(libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform']), '.gem')))
173
- FileUtils.mkdir_p(File.join(vendor_path, 'specifications'))
174
- File.open(File.join(vendor_path, 'specifications', File.basename(libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform']), '.gem') + '.gemspec'), 'wb') { |f| f.write(package.spec.to_ruby) }
153
+ package = Gem::Package.new(File.join(vendor_path, libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform'])))
154
+ package.extract_files(File.join(vendor_path, File.basename(libv8_downloaded_gem(libv8_gem_name, version['number'], version['platform']), '.gem')))
175
155
 
176
156
  libv8_vendor_path
177
157
  end
178
158
 
179
159
  def ensure_libv8_load_path
180
- puts "platform ruby:#{RUBY_PLATFORM} rubygems:#{Gem::Platform.new(RUBY_PLATFORM)} detected:#{ruby_platform}"
160
+ puts "detected platform #{RUBY_PLATFORM} => #{ruby_platform}"
181
161
 
182
- libv8_path, spec = libv8_local_path
183
- if !ENV['ONLY_INSTALLED_LIBV8_GEM'] && !libv8_path
184
- libv8_path, spec = libv8_vendor_path || libv8_vendor!
185
- end
162
+ libv8_path = libv8_local_path || libv8_vendor_path || libv8_vendor!
186
163
 
187
164
  abort(<<-ERROR) unless libv8_path
188
165
  ERROR: could not find #{libv8_gem_name}
@@ -194,7 +171,7 @@ end
194
171
 
195
172
  ensure_libv8_load_path
196
173
 
197
- require 'libv8-node'
174
+ require 'libv8'
198
175
 
199
176
  IS_DARWIN = RUBY_PLATFORM =~ /darwin/
200
177
 
@@ -213,8 +190,6 @@ cppflags_add_cpu_extension!
213
190
  $CPPFLAGS += " -Wno-reserved-user-defined-literal" if IS_DARWIN
214
191
 
215
192
  $LDFLAGS.insert(0, " -stdlib=libc++ ") if IS_DARWIN
216
- $LDFLAGS += " -Wl,--no-undefined " unless IS_DARWIN
217
- $LDFLAGS += " -Wl,-undefined,error " if IS_DARWIN
218
193
 
219
194
  if ENV['CXX']
220
195
  puts "SETTING CXX"
@@ -253,7 +228,7 @@ if enable_config('debug') || enable_config('asan')
253
228
  CONFIG['debugflags'] << ' -ggdb3 -O0'
254
229
  end
255
230
 
256
- Libv8::Node.configure_makefile
231
+ Libv8.configure_makefile
257
232
 
258
233
  if enable_config('asan')
259
234
  $CPPFLAGS.insert(0, " -fsanitize=address ")
@@ -23,7 +23,9 @@
23
23
  #if RUBY_API_VERSION_MAJOR > 1
24
24
  #include <ruby/thread.h>
25
25
  #endif
26
+ #include <ruby/io.h>
26
27
  #include <v8.h>
28
+ #include <v8-profiler.h>
27
29
  #include <libplatform/libplatform.h>
28
30
  #include <ruby/encoding.h>
29
31
  #include <pthread.h>
@@ -174,7 +176,7 @@ static VALUE rb_mJSON;
174
176
  static VALUE rb_cFailedV8Conversion;
175
177
  static VALUE rb_cDateTime = Qnil;
176
178
 
177
- static Platform* current_platform = NULL;
179
+ static std::unique_ptr<Platform> current_platform = NULL;
178
180
  static std::mutex platform_lock;
179
181
 
180
182
  static VALUE rb_platform_set_flag_as_str(VALUE _klass, VALUE flag_as_str) {
@@ -211,8 +213,8 @@ static void init_v8() {
211
213
 
212
214
  if (current_platform == NULL) {
213
215
  V8::InitializeICU();
214
- current_platform = platform::CreateDefaultPlatform();
215
- V8::InitializePlatform(current_platform);
216
+ current_platform = platform::NewDefaultPlatform();
217
+ V8::InitializePlatform(current_platform.get());
216
218
  V8::Initialize();
217
219
  }
218
220
 
@@ -254,16 +256,16 @@ static void prepare_result(MaybeLocal<Value> v8res,
254
256
  Local<Value> local_value = v8res.ToLocalChecked();
255
257
  if ((local_value->IsObject() || local_value->IsArray()) &&
256
258
  !local_value->IsDate() && !local_value->IsFunction()) {
257
- Local<Object> JSON = context->Global()->Get(
258
- String::NewFromUtf8(isolate, "JSON"))->ToObject();
259
+ Local<Object> JSON = context->Global()->Get(String::NewFromUtf8(isolate, "JSON"))
260
+ ->ToObject(context).ToLocalChecked();
259
261
 
260
262
  Local<Function> stringify = JSON->Get(v8::String::NewFromUtf8(isolate, "stringify"))
261
263
  .As<Function>();
262
264
 
263
- Local<Object> object = local_value->ToObject();
265
+ Local<Object> object = local_value->ToObject(context).ToLocalChecked();
264
266
  const unsigned argc = 1;
265
267
  Local<Value> argv[argc] = { object };
266
- MaybeLocal<Value> json = stringify->Call(JSON, argc, argv);
268
+ MaybeLocal<Value> json = stringify->Call(context, JSON, argc, argv);
267
269
 
268
270
  if (json.IsEmpty()) {
269
271
  evalRes.executed = false;
@@ -287,11 +289,21 @@ static void prepare_result(MaybeLocal<Value> v8res,
287
289
  evalRes.message = new Persistent<Value>();
288
290
  Local<Message> message = trycatch.Message();
289
291
  char buf[1000];
290
- int len;
292
+ int len, line, column;
293
+
294
+ if (!message->GetLineNumber(context).To(&line)) {
295
+ line = 0;
296
+ }
297
+
298
+ if (!message->GetStartColumn(context).To(&column)) {
299
+ column = 0;
300
+ }
301
+
291
302
  len = snprintf(buf, sizeof(buf), "%s at %s:%i:%i", *String::Utf8Value(isolate, message->Get()),
292
- *String::Utf8Value(isolate, message->GetScriptResourceName()->ToString()),
293
- message->GetLineNumber(),
294
- message->GetStartColumn());
303
+ *String::Utf8Value(isolate, message->GetScriptResourceName()->ToString(context).ToLocalChecked()),
304
+ line,
305
+ column);
306
+
295
307
  if ((size_t) len >= sizeof(buf)) {
296
308
  len = sizeof(buf) - 1;
297
309
  buf[len] = '\0';
@@ -307,7 +319,8 @@ static void prepare_result(MaybeLocal<Value> v8res,
307
319
  }
308
320
  if (!trycatch.StackTrace(context).IsEmpty()) {
309
321
  evalRes.backtrace = new Persistent<Value>();
310
- evalRes.backtrace->Reset(isolate, trycatch.StackTrace(context).ToLocalChecked()->ToString());
322
+ evalRes.backtrace->Reset(isolate,
323
+ trycatch.StackTrace(context).ToLocalChecked()->ToString(context).ToLocalChecked());
311
324
  }
312
325
  }
313
326
  }
@@ -391,11 +404,11 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
391
404
  }
392
405
 
393
406
  if (value->IsInt32()) {
394
- return INT2FIX(value->Int32Value());
407
+ return INT2FIX(value->Int32Value(context).ToChecked());
395
408
  }
396
409
 
397
410
  if (value->IsNumber()) {
398
- return rb_float_new(value->NumberValue());
411
+ return rb_float_new(value->NumberValue(context).ToChecked());
399
412
  }
400
413
 
401
414
  if (value->IsTrue()) {
@@ -436,7 +449,7 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
436
449
  VALUE rb_hash = rb_hash_new();
437
450
  TryCatch trycatch(isolate);
438
451
 
439
- Local<Object> object = value->ToObject();
452
+ Local<Object> object = value->ToObject(context).ToLocalChecked();
440
453
  auto maybe_props = object->GetOwnPropertyNames(context);
441
454
  if (!maybe_props.IsEmpty()) {
442
455
  Local<Array> props = maybe_props.ToLocalChecked();
@@ -459,8 +472,8 @@ static VALUE convert_v8_to_ruby(Isolate* isolate, Local<Context> context,
459
472
  return rb_hash;
460
473
  }
461
474
 
462
- Local<String> rstr = value->ToString();
463
- return rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
475
+ Local<String> rstr = value->ToString(context).ToLocalChecked();
476
+ return rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate), rb_enc_find("utf-8"));
464
477
  }
465
478
 
466
479
  static VALUE convert_v8_to_ruby(Isolate* isolate,
@@ -557,7 +570,7 @@ treat_as_latin1:
557
570
  return v8str.ToLocalChecked();
558
571
  }
559
572
 
560
- static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value)
573
+ static Local<Value> convert_ruby_to_v8(Isolate* isolate, Local<Context> context, VALUE value)
561
574
  {
562
575
  EscapableHandleScope scope(isolate);
563
576
 
@@ -571,87 +584,86 @@ static Local<Value> convert_ruby_to_v8(Isolate* isolate, VALUE value)
571
584
  VALUE klass;
572
585
 
573
586
  switch (TYPE(value)) {
574
- case T_FIXNUM:
587
+ case T_FIXNUM:
575
588
  {
576
- fixnum = NUM2LONG(value);
577
- if (fixnum > INT_MAX)
578
- {
579
- return scope.Escape(Number::New(isolate, (double)fixnum));
580
- }
581
- return scope.Escape(Integer::New(isolate, (int)fixnum));
589
+ fixnum = NUM2LONG(value);
590
+ if (fixnum > INT_MAX)
591
+ {
592
+ return scope.Escape(Number::New(isolate, (double)fixnum));
593
+ }
594
+ return scope.Escape(Integer::New(isolate, (int)fixnum));
582
595
  }
583
- case T_FLOAT:
584
- return scope.Escape(Number::New(isolate, NUM2DBL(value)));
585
- case T_STRING:
596
+ case T_FLOAT:
597
+ return scope.Escape(Number::New(isolate, NUM2DBL(value)));
598
+ case T_STRING:
586
599
  return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
587
- case T_NIL:
588
- return scope.Escape(Null(isolate));
589
- case T_TRUE:
590
- return scope.Escape(True(isolate));
591
- case T_FALSE:
592
- return scope.Escape(False(isolate));
593
- case T_ARRAY:
600
+ case T_NIL:
601
+ return scope.Escape(Null(isolate));
602
+ case T_TRUE:
603
+ return scope.Escape(True(isolate));
604
+ case T_FALSE:
605
+ return scope.Escape(False(isolate));
606
+ case T_ARRAY:
594
607
  {
595
- length = RARRAY_LEN(value);
596
- array = Array::New(isolate, (int)length);
597
- for(i=0; i<length; i++) {
598
- array->Set(i, convert_ruby_to_v8(isolate, rb_ary_entry(value, i)));
599
- }
600
- return scope.Escape(array);
608
+ length = RARRAY_LEN(value);
609
+ array = Array::New(isolate, (int)length);
610
+ for(i=0; i<length; i++) {
611
+ array->Set(i, convert_ruby_to_v8(isolate, context, rb_ary_entry(value, i)));
612
+ }
613
+ return scope.Escape(array);
601
614
  }
602
- case T_HASH:
615
+ case T_HASH:
603
616
  {
604
- object = Object::New(isolate);
605
- hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
606
- length = RARRAY_LEN(hash_as_array);
607
- for(i=0; i<length; i++) {
608
- pair = rb_ary_entry(hash_as_array, i);
609
- object->Set(convert_ruby_to_v8(isolate, rb_ary_entry(pair, 0)),
610
- convert_ruby_to_v8(isolate, rb_ary_entry(pair, 1)));
611
- }
612
- return scope.Escape(object);
617
+ object = Object::New(isolate);
618
+ hash_as_array = rb_funcall(value, rb_intern("to_a"), 0);
619
+ length = RARRAY_LEN(hash_as_array);
620
+ for(i=0; i<length; i++) {
621
+ pair = rb_ary_entry(hash_as_array, i);
622
+ object->Set(convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 0)),
623
+ convert_ruby_to_v8(isolate, context, rb_ary_entry(pair, 1)));
624
+ }
625
+ return scope.Escape(object);
613
626
  }
614
- case T_SYMBOL:
627
+ case T_SYMBOL:
615
628
  {
616
- value = rb_funcall(value, rb_intern("to_s"), 0);
629
+ value = rb_funcall(value, rb_intern("to_s"), 0);
617
630
  return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
618
631
  }
619
- case T_DATA:
632
+ case T_DATA:
633
+ {
634
+ klass = rb_funcall(value, rb_intern("class"), 0);
635
+ if (klass == rb_cTime || klass == rb_cDateTime)
620
636
  {
621
- klass = rb_funcall(value, rb_intern("class"), 0);
622
- if (klass == rb_cTime || klass == rb_cDateTime)
637
+ if (klass == rb_cDateTime)
623
638
  {
624
- if (klass == rb_cDateTime)
625
- {
626
- value = rb_funcall(value, rb_intern("to_time"), 0);
627
- }
628
- value = rb_funcall(value, rb_intern("to_f"), 0);
629
- return scope.Escape(Date::New(isolate, NUM2DBL(value) * 1000));
639
+ value = rb_funcall(value, rb_intern("to_time"), 0);
630
640
  }
641
+ value = rb_funcall(value, rb_intern("to_f"), 0);
642
+ return scope.Escape(Date::New(context, NUM2DBL(value) * 1000).ToLocalChecked());
643
+ }
631
644
  // break intentionally missing
632
645
  }
633
- case T_OBJECT:
634
- case T_CLASS:
635
- case T_ICLASS:
636
- case T_MODULE:
637
- case T_REGEXP:
638
- case T_MATCH:
639
- case T_STRUCT:
640
- case T_BIGNUM:
641
- case T_FILE:
642
- case T_UNDEF:
643
- case T_NODE:
644
- default:
646
+ case T_OBJECT:
647
+ case T_CLASS:
648
+ case T_ICLASS:
649
+ case T_MODULE:
650
+ case T_REGEXP:
651
+ case T_MATCH:
652
+ case T_STRUCT:
653
+ case T_BIGNUM:
654
+ case T_FILE:
655
+ case T_UNDEF:
656
+ case T_NODE:
657
+ default:
645
658
  {
646
659
  if (rb_respond_to(value, rb_intern("to_s"))) {
647
660
  // TODO: if this throws we're screwed
648
661
  value = rb_funcall(value, rb_intern("to_s"), 0);
649
662
  return scope.Escape(convert_ruby_str_to_v8(scope, isolate, value));
650
663
  }
651
- return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
652
- }
664
+ return scope.Escape(String::NewFromUtf8(isolate, "Undefined Conversion"));
665
+ }
653
666
  }
654
-
655
667
  }
656
668
 
657
669
  static void unblock_eval(void *ptr) {
@@ -659,6 +671,91 @@ static void unblock_eval(void *ptr) {
659
671
  eval->context_info->isolate_info->interrupted = true;
660
672
  }
661
673
 
674
+ /*
675
+ * The implementations of the run_extra_code(), create_snapshot_data_blob() and
676
+ * warm_up_snapshot_data_blob() functions have been derived from V8's test suite.
677
+ */
678
+ bool run_extra_code(Isolate *isolate, Local<v8::Context> context,
679
+ const char *utf8_source, const char *name) {
680
+ Context::Scope context_scope(context);
681
+ TryCatch try_catch(isolate);
682
+ Local<String> source_string;
683
+ if (!String::NewFromUtf8(isolate, utf8_source,
684
+ NewStringType::kNormal)
685
+ .ToLocal(&source_string)) {
686
+ return false;
687
+ }
688
+ Local<v8::String> resource_name =
689
+ String::NewFromUtf8(isolate, name, NewStringType::kNormal)
690
+ .ToLocalChecked();
691
+ ScriptOrigin origin(resource_name);
692
+ ScriptCompiler::Source source(source_string, origin);
693
+ Local<Script> script;
694
+ if (!ScriptCompiler::Compile(context, &source).ToLocal(&script))
695
+ return false;
696
+ if (script->Run(context).IsEmpty())
697
+ return false;
698
+ // CHECK(!try_catch.HasCaught());
699
+ return true;
700
+ }
701
+
702
+ StartupData
703
+ create_snapshot_data_blob(const char *embedded_source = nullptr) {
704
+ // Create a new isolate and a new context from scratch, optionally run
705
+ // a script to embed, and serialize to create a snapshot blob.
706
+ StartupData result = {nullptr, 0};
707
+ {
708
+ SnapshotCreator snapshot_creator;
709
+ Isolate *isolate = snapshot_creator.GetIsolate();
710
+ {
711
+ HandleScope scope(isolate);
712
+ Local<Context> context = Context::New(isolate);
713
+ if (embedded_source != nullptr &&
714
+ !run_extra_code(isolate, context, embedded_source,
715
+ "<embedded>")) {
716
+ return result;
717
+ }
718
+ snapshot_creator.SetDefaultContext(context);
719
+ }
720
+ result = snapshot_creator.CreateBlob(
721
+ SnapshotCreator::FunctionCodeHandling::kClear);
722
+ }
723
+ return result;
724
+ }
725
+
726
+ StartupData warm_up_snapshot_data_blob(StartupData cold_snapshot_blob,
727
+ const char *warmup_source) {
728
+ // Use following steps to create a warmed up snapshot blob from a cold one:
729
+ // - Create a new isolate from the cold snapshot.
730
+ // - Create a new context to run the warmup script. This will trigger
731
+ // compilation of executed functions.
732
+ // - Create a new context. This context will be unpolluted.
733
+ // - Serialize the isolate and the second context into a new snapshot blob.
734
+ StartupData result = {nullptr, 0};
735
+
736
+ if (cold_snapshot_blob.raw_size > 0 && cold_snapshot_blob.data != nullptr &&
737
+ warmup_source != NULL) {
738
+ SnapshotCreator snapshot_creator(nullptr, &cold_snapshot_blob);
739
+ Isolate *isolate = snapshot_creator.GetIsolate();
740
+ {
741
+ HandleScope scope(isolate);
742
+ Local<Context> context = Context::New(isolate);
743
+ if (!run_extra_code(isolate, context, warmup_source, "<warm-up>")) {
744
+ return result;
745
+ }
746
+ }
747
+ {
748
+ HandleScope handle_scope(isolate);
749
+ isolate->ContextDisposedNotification(false);
750
+ Local<Context> context = Context::New(isolate);
751
+ snapshot_creator.SetDefaultContext(context);
752
+ }
753
+ result = snapshot_creator.CreateBlob(
754
+ SnapshotCreator::FunctionCodeHandling::kKeep);
755
+ }
756
+ return result;
757
+ }
758
+
662
759
  static VALUE rb_snapshot_size(VALUE self, VALUE str) {
663
760
  SnapshotInfo* snapshot_info;
664
761
  Data_Get_Struct(self, SnapshotInfo, snapshot_info);
@@ -677,7 +774,7 @@ static VALUE rb_snapshot_load(VALUE self, VALUE str) {
677
774
 
678
775
  init_v8();
679
776
 
680
- StartupData startup_data = V8::CreateSnapshotDataBlob(RSTRING_PTR(str));
777
+ StartupData startup_data = create_snapshot_data_blob(RSTRING_PTR(str));
681
778
 
682
779
  if (startup_data.data == NULL && startup_data.raw_size == 0) {
683
780
  rb_raise(rb_eSnapshotError, "Could not create snapshot, most likely the source is incorrect");
@@ -708,7 +805,7 @@ static VALUE rb_snapshot_warmup_unsafe(VALUE self, VALUE str) {
708
805
  init_v8();
709
806
 
710
807
  StartupData cold_startup_data = {snapshot_info->data, snapshot_info->raw_size};
711
- StartupData warm_startup_data = V8::WarmUpSnapshotDataBlob(cold_startup_data, RSTRING_PTR(str));
808
+ StartupData warm_startup_data = warm_up_snapshot_data_blob(cold_startup_data, RSTRING_PTR(str));
712
809
 
713
810
  if (warm_startup_data.data == NULL && warm_startup_data.raw_size == 0) {
714
811
  rb_raise(rb_eSnapshotError, "Could not warm up snapshot, most likely the source is incorrect");
@@ -887,8 +984,8 @@ static VALUE convert_result_to_ruby(VALUE self /* context */,
887
984
  Local<Value> tmp = Local<Value>::New(isolate, *result.value);
888
985
 
889
986
  if (result.json) {
890
- Local<String> rstr = tmp->ToString();
891
- VALUE json_string = rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(), rb_enc_find("utf-8"));
987
+ Local<String> rstr = tmp->ToString(p_ctx->Get(isolate)).ToLocalChecked();
988
+ VALUE json_string = rb_enc_str_new(*String::Utf8Value(isolate, rstr), rstr->Utf8Length(isolate), rb_enc_find("utf-8"));
892
989
  ret = rb_funcall(rb_mJSON, rb_intern("parse"), 1, json_string);
893
990
  } else {
894
991
  ret = convert_v8_to_ruby(isolate, *p_ctx, tmp);
@@ -1009,6 +1106,8 @@ gvl_ruby_callback(void* data) {
1009
1106
  VALUE result;
1010
1107
  VALUE self;
1011
1108
  VALUE parent;
1109
+ ContextInfo* context_info;
1110
+
1012
1111
  {
1013
1112
  HandleScope scope(args->GetIsolate());
1014
1113
  Local<External> external = Local<External>::Cast(args->Data());
@@ -1021,7 +1120,6 @@ gvl_ruby_callback(void* data) {
1021
1120
  return NULL;
1022
1121
  }
1023
1122
 
1024
- ContextInfo* context_info;
1025
1123
  Data_Get_Struct(parent, ContextInfo, context_info);
1026
1124
 
1027
1125
  if (length > 0) {
@@ -1031,7 +1129,7 @@ gvl_ruby_callback(void* data) {
1031
1129
  for (int i = 0; i < length; i++) {
1032
1130
  Local<Value> value = ((*args)[i]).As<Value>();
1033
1131
  VALUE tmp = convert_v8_to_ruby(args->GetIsolate(),
1034
- *context_info->context, value);
1132
+ *context_info->context, value);
1035
1133
  rb_ary_push(ruby_args, tmp);
1036
1134
  }
1037
1135
  }
@@ -1062,7 +1160,7 @@ gvl_ruby_callback(void* data) {
1062
1160
  }
1063
1161
  else {
1064
1162
  HandleScope scope(args->GetIsolate());
1065
- Handle<Value> v8_result = convert_ruby_to_v8(args->GetIsolate(), result);
1163
+ Handle<Value> v8_result = convert_ruby_to_v8(args->GetIsolate(), context_info->context->Get(args->GetIsolate()), result);
1066
1164
  args->GetReturnValue().Set(v8_result);
1067
1165
  }
1068
1166
 
@@ -1119,8 +1217,10 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1119
1217
  Local<Context> context = context_info->context->Get(isolate);
1120
1218
  Context::Scope context_scope(context);
1121
1219
 
1122
- Local<String> v8_str = String::NewFromUtf8(isolate, RSTRING_PTR(name),
1123
- NewStringType::kNormal, (int)RSTRING_LEN(name)).ToLocalChecked();
1220
+ Local<String> v8_str =
1221
+ String::NewFromUtf8(isolate, RSTRING_PTR(name),
1222
+ NewStringType::kNormal, (int)RSTRING_LEN(name))
1223
+ .ToLocalChecked();
1124
1224
 
1125
1225
  // copy self so we can access from v8 external
1126
1226
  VALUE* self_copy;
@@ -1130,23 +1230,34 @@ static VALUE rb_external_function_notify_v8(VALUE self) {
1130
1230
  Local<Value> external = External::New(isolate, self_copy);
1131
1231
 
1132
1232
  if (parent_object == Qnil) {
1133
- context->Global()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
1134
- } else {
1233
+ context->Global()->Set(
1234
+ v8_str, FunctionTemplate::New(isolate, ruby_callback, external)
1235
+ ->GetFunction(context)
1236
+ .ToLocalChecked());
1135
1237
 
1136
- Local<String> eval = String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
1137
- NewStringType::kNormal, (int)RSTRING_LEN(parent_object_eval)).ToLocalChecked();
1238
+ } else {
1239
+ Local<String> eval =
1240
+ String::NewFromUtf8(isolate, RSTRING_PTR(parent_object_eval),
1241
+ NewStringType::kNormal,
1242
+ (int)RSTRING_LEN(parent_object_eval))
1243
+ .ToLocalChecked();
1138
1244
 
1139
1245
  MaybeLocal<Script> parsed_script = Script::Compile(context, eval);
1140
1246
  if (parsed_script.IsEmpty()) {
1141
1247
  parse_error = true;
1142
1248
  } else {
1143
- MaybeLocal<Value> maybe_value = parsed_script.ToLocalChecked()->Run(context);
1249
+ MaybeLocal<Value> maybe_value =
1250
+ parsed_script.ToLocalChecked()->Run(context);
1144
1251
  attach_error = true;
1145
1252
 
1146
1253
  if (!maybe_value.IsEmpty()) {
1147
1254
  Local<Value> value = maybe_value.ToLocalChecked();
1148
- if (value->IsObject()){
1149
- value.As<Object>()->Set(v8_str, FunctionTemplate::New(isolate, ruby_callback, external)->GetFunction());
1255
+ if (value->IsObject()) {
1256
+ value.As<Object>()->Set(
1257
+ v8_str, FunctionTemplate::New(
1258
+ isolate, ruby_callback, external)
1259
+ ->GetFunction(context)
1260
+ .ToLocalChecked());
1150
1261
  attach_error = false;
1151
1262
  }
1152
1263
  }
@@ -1350,6 +1461,69 @@ rb_heap_stats(VALUE self) {
1350
1461
  return rval;
1351
1462
  }
1352
1463
 
1464
+ // https://github.com/bnoordhuis/node-heapdump/blob/master/src/heapdump.cc
1465
+ class FileOutputStream : public OutputStream {
1466
+ public:
1467
+ FileOutputStream(FILE* stream) : stream_(stream) {}
1468
+
1469
+ virtual int GetChunkSize() {
1470
+ return 65536;
1471
+ }
1472
+
1473
+ virtual void EndOfStream() {}
1474
+
1475
+ virtual WriteResult WriteAsciiChunk(char* data, int size) {
1476
+ const size_t len = static_cast<size_t>(size);
1477
+ size_t off = 0;
1478
+
1479
+ while (off < len && !feof(stream_) && !ferror(stream_))
1480
+ off += fwrite(data + off, 1, len - off, stream_);
1481
+
1482
+ return off == len ? kContinue : kAbort;
1483
+ }
1484
+
1485
+ private:
1486
+ FILE* stream_;
1487
+ };
1488
+
1489
+
1490
+ static VALUE
1491
+ rb_heap_snapshot(VALUE self, VALUE file) {
1492
+
1493
+ rb_io_t *fptr;
1494
+
1495
+ fptr = RFILE(file)->fptr;
1496
+
1497
+ if (!fptr) return Qfalse;
1498
+
1499
+ FILE* fp;
1500
+ fp = fdopen(fptr->fd, "w");
1501
+ if (fp == NULL) return Qfalse;
1502
+
1503
+
1504
+ ContextInfo* context_info;
1505
+ Data_Get_Struct(self, ContextInfo, context_info);
1506
+ Isolate* isolate;
1507
+ isolate = context_info->isolate_info ? context_info->isolate_info->isolate : NULL;
1508
+
1509
+ if (!isolate) return Qfalse;
1510
+
1511
+ Locker lock(isolate);
1512
+ Isolate::Scope isolate_scope(isolate);
1513
+ HandleScope handle_scope(isolate);
1514
+
1515
+ HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
1516
+
1517
+ const HeapSnapshot* const snap = heap_profiler->TakeHeapSnapshot();
1518
+
1519
+ FileOutputStream stream(fp);
1520
+ snap->Serialize(&stream, HeapSnapshot::kJSON);
1521
+
1522
+ const_cast<HeapSnapshot*>(snap)->Delete();
1523
+
1524
+ return Qtrue;
1525
+ }
1526
+
1353
1527
  static VALUE
1354
1528
  rb_context_stop(VALUE self) {
1355
1529
 
@@ -1494,7 +1668,7 @@ static VALUE rb_context_call_unsafe(int argc, VALUE *argv, VALUE self) {
1494
1668
  return Qnil;
1495
1669
  }
1496
1670
  for(int i=0; i < fun_argc; i++) {
1497
- call.argv[i] = convert_ruby_to_v8(isolate, call_argv[i]);
1671
+ call.argv[i] = convert_ruby_to_v8(isolate, context, call_argv[i]);
1498
1672
  }
1499
1673
  }
1500
1674
  #if RUBY_API_VERSION_MAJOR > 1
@@ -1558,6 +1732,8 @@ extern "C" {
1558
1732
  rb_define_method(rb_cContext, "dispose_unsafe", (VALUE(*)(...))&rb_context_dispose, 0);
1559
1733
  rb_define_method(rb_cContext, "low_memory_notification", (VALUE(*)(...))&rb_context_low_memory_notification, 0);
1560
1734
  rb_define_method(rb_cContext, "heap_stats", (VALUE(*)(...))&rb_heap_stats, 0);
1735
+ rb_define_method(rb_cContext, "write_heap_snapshot_unsafe", (VALUE(*)(...))&rb_heap_snapshot, 1);
1736
+
1561
1737
  rb_define_private_method(rb_cContext, "create_isolate_value",(VALUE(*)(...))&rb_context_create_isolate_value, 0);
1562
1738
  rb_define_private_method(rb_cContext, "eval_unsafe",(VALUE(*)(...))&rb_context_eval_unsafe, 2);
1563
1739
  rb_define_private_method(rb_cContext, "call_unsafe", (VALUE(*)(...))&rb_context_call_unsafe, -1);
@@ -178,6 +178,28 @@ module MiniRacer
178
178
  eval(File.read(filename))
179
179
  end
180
180
 
181
+ def write_heap_snapshot(file_or_io)
182
+ f = nil
183
+ implicit = false
184
+
185
+
186
+ if String === file_or_io
187
+ f = File.open(file_or_io, "w")
188
+ implicit = true
189
+ else
190
+ f = file_or_io
191
+ end
192
+
193
+ if !(File === f)
194
+ raise ArgumentError("file_or_io")
195
+ end
196
+
197
+ write_heap_snapshot_unsafe(f)
198
+
199
+ ensure
200
+ f.close if implicit
201
+ end
202
+
181
203
  def eval(str, options=nil)
182
204
  raise(ContextDisposedError, 'attempted to call eval on a disposed context!') if @disposed
183
205
 
@@ -2,6 +2,6 @@ module Sqreen
2
2
  module MiniRacer
3
3
  # part before qualifier is the number of the last upstream release
4
4
  # since we synced with it
5
- VERSION = "0.2.4.0.2"
5
+ VERSION = "0.2.5.0.1.beta1"
6
6
  end
7
7
  end
data/mini_racer.gemspec CHANGED
@@ -15,12 +15,13 @@ Gem::Specification.new do |spec|
15
15
  spec.license = "MIT"
16
16
 
17
17
 
18
- REJECTS = %r{\A((benchmark|test|spec|features)/|bench\.rb|.+\.sh|Jenkinsfile)}
18
+ REJECTS = %r{\A((benchmark|test|spec|features|examples)/|bench\.rb|.+\.sh|Jenkinsfile)}
19
19
  spec.files = `git ls-files -z`.split("\x0").reject { |f| f.match(REJECTS) }
20
20
  spec.bindir = "exe"
21
21
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
22
22
  spec.require_paths = ["lib"]
23
23
 
24
+ spec.add_development_dependency "bundler", "~> 1.12"
24
25
  spec.add_development_dependency "rake", "~> 10.0"
25
26
  spec.add_development_dependency "minitest", "~> 5.0"
26
27
  spec.add_development_dependency "rake-compiler"
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sq_mini_racer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.4.0.2
4
+ version: 0.2.5.0.1.beta1
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: 2019-08-26 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: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: rake
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -61,18 +75,14 @@ extensions:
61
75
  - ext/prv_ext_loader/extconf.rb
62
76
  extra_rdoc_files: []
63
77
  files:
64
- - ".dockerignore"
65
78
  - ".gitignore"
66
79
  - ".travis.yml"
67
80
  - CHANGELOG
68
81
  - CODE_OF_CONDUCT.md
69
- - Dockerfile
70
82
  - Gemfile
71
83
  - LICENSE.txt
72
84
  - README.md
73
85
  - Rakefile
74
- - azure-pipelines.yml
75
- - azure-template.yml
76
86
  - bin/console
77
87
  - bin/setup
78
88
  - ext/mini_racer_extension/compat.hpp
@@ -88,7 +98,7 @@ homepage: https://github.com/sqreen/mini_racer
88
98
  licenses:
89
99
  - MIT
90
100
  metadata: {}
91
- post_install_message:
101
+ post_install_message:
92
102
  rdoc_options: []
93
103
  require_paths:
94
104
  - lib
@@ -100,12 +110,13 @@ required_ruby_version: !ruby/object:Gem::Requirement
100
110
  version: 1.9.3
101
111
  required_rubygems_version: !ruby/object:Gem::Requirement
102
112
  requirements:
103
- - - ">="
113
+ - - ">"
104
114
  - !ruby/object:Gem::Version
105
- version: '0'
115
+ version: 1.3.1
106
116
  requirements: []
107
- rubygems_version: 3.1.3
108
- signing_key:
117
+ rubyforge_project:
118
+ rubygems_version: 2.7.7
119
+ signing_key:
109
120
  specification_version: 4
110
121
  summary: Minimal embedded v8 for Ruby
111
122
  test_files: []
data/.dockerignore DELETED
@@ -1,12 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- Gemfile.lock
4
- /_yardoc/
5
- /coverage/
6
- /doc/
7
- /pkg/
8
- /spec/reports/
9
- /tmp/
10
- lib/sq_mini_racer_extension.so
11
- lib/sq_mini_racer_loader.so
12
- *.bundle
data/Dockerfile DELETED
@@ -1,22 +0,0 @@
1
- ARG RUBY_VERSION=2.7
2
- FROM ruby:${RUBY_VERSION}
3
-
4
- RUN test ! -f /etc/alpine-release || apk add --no-cache build-base git
5
-
6
- # without this `COPY .git`, we get the following error:
7
- # fatal: not a git repository (or any of the parent directories): .git
8
- # but with it we need the full gem just to compile the extension because
9
- # of gemspec's `git --ls-files`
10
- # COPY .git /code/.git
11
-
12
- COPY Gemfile mini_racer.gemspec /code/
13
- COPY lib/sqreen/mini_racer/version.rb /code/lib/sqreen/mini_racer/version.rb
14
- WORKDIR /code
15
- RUN bundle install
16
-
17
- COPY Rakefile /code/
18
- COPY ext /code/ext/
19
- RUN bundle exec rake compile
20
-
21
- COPY . /code/
22
- CMD bundle exec irb -rmini_racer
data/azure-pipelines.yml DELETED
@@ -1,69 +0,0 @@
1
- jobs:
2
- - template: azure-template.yml
3
- parameters:
4
- name: linux_2_0
5
- displayName: Linux Ruby 2.0
6
- rubyVersion: '2.0'
7
- publishCoverage: true
8
-
9
- - template: azure-template.yml
10
- parameters:
11
- name: linux_2_1
12
- displayName: Linux Ruby 2.1
13
- rubyVersion: '2.1'
14
-
15
- - template: azure-template.yml
16
- parameters:
17
- name: linux_2_2
18
- displayName: Linux Ruby 2.2
19
- rubyVersion: '2.2'
20
-
21
- - template: azure-template.yml
22
- parameters:
23
- name: linux_2_3
24
- displayName: Linux Ruby 2.3
25
- rubyVersion: '2.3'
26
-
27
- - template: azure-template.yml
28
- parameters:
29
- name: linux_2_4
30
- displayName: Linux Ruby 2.4
31
- rubyVersion: '2.4'
32
-
33
- - template: azure-template.yml
34
- parameters:
35
- name: linux_2_5
36
- displayName: Linux Ruby 2.5
37
- rubyVersion: '2.5'
38
-
39
- - template: azure-template.yml
40
- parameters:
41
- name: linux_2_6
42
- displayName: Linux Ruby 2.6
43
- rubyVersion: '2.6'
44
-
45
- - template: azure-template.yml
46
- parameters:
47
- name: linux_2_7
48
- displayName: Linux Ruby 2.7
49
- rubyVersion: '2.7'
50
-
51
- - template: azure-template.yml
52
- parameters:
53
- name: linux_2_7_mini_racer
54
- displayName: Linux Ruby 2.7 (with mini_racer)
55
- rubyVersion: '2.7'
56
- with_mini_racer: true
57
-
58
- - template: azure-template.yml
59
- parameters:
60
- name: linux_2_7_therubyracer
61
- displayName: Linux Ruby 2.7 (with therubyracer)
62
- rubyVersion: '2.7'
63
- with_therubyracer: true
64
-
65
- - template: azure-template.yml
66
- parameters:
67
- name: macos_10_15
68
- displayName: MacOS 10.15
69
- imageName: 'macos-10.15'
data/azure-template.yml DELETED
@@ -1,92 +0,0 @@
1
- parameters:
2
- name: ~
3
- displayName: ~
4
- rubyVersion: bundled
5
- imageName: ubuntu-18.04
6
- publishCoverage: false
7
- with_mini_racer: false
8
- with_therubyracer: false
9
-
10
- jobs:
11
- - job: ${{ parameters.name }}
12
- displayName: ${{ parameters.displayName }}
13
- pool:
14
- vmImage: ${{ parameters.imageName }}
15
-
16
- variables:
17
- TESTOPTS: -v
18
- ${{ if eq(parameters.publishCoverage, true) }}:
19
- CPPFLAGS: --coverage
20
- LDFLAGS: --coverage
21
- ${{ if eq(parameters.rubyVersion, 'bundled') }}:
22
- gem: gem
23
- bundle: bundle
24
- ${{ if ne(parameters.rubyVersion, 'bundled') }}:
25
- gem: /opt/ruby/${{ parameters.rubyVersion }}/bin/gem
26
- bundle: /opt/ruby/${{ parameters.rubyVersion }}/bin/bundle
27
- GEM_HOME: /opt/ruby/${{ parameters.rubyVersion }}/lib/ruby/gems/${{ parameters.rubyVersion }}.0
28
-
29
- steps:
30
- - checkout: self
31
- displayName: Checkout
32
- clean: true
33
- submodules: recursive
34
-
35
- - ${{ if ne(parameters.rubyVersion, 'bundled') }}:
36
- - script: |
37
- sudo apt-get install -y gnupg
38
- sudo apt-key adv --keyserver keyserver.ubuntu.com --recv 5D98E7264E3F3D89463B314B12229434A9F003C9
39
- echo deb [arch=amd64] http://sqreen-download-private.s3.amazonaws.com/deb bionic main | sudo tee -a /etc/apt/sources.list
40
- sudo apt-get update
41
- sudo apt-get install -y sq-ruby${{ parameters.rubyVersion }} ruby-
42
- displayName: Install Ruby
43
-
44
- - ${{ if eq(parameters.rubyVersion, 'bundled') }}:
45
- - script: sudo $(gem) install bundler --version '< 2.0' --no-document
46
- displayName: Install bundler
47
-
48
- - ${{ if eq(parameters.imageName, 'ubuntu-18.04') }}:
49
- - script: |
50
- sudo apt-get install -y build-essential git curl valgrind g++ make
51
- displayName: Install Linux packages
52
-
53
- - script: $(bundle) install --path vendor/bundle
54
- displayName: Install gem dependencies
55
- env:
56
- ${{ if eq(parameters.with_mini_racer, true) }}:
57
- LOAD_MINI_RACER: 1
58
- ${{ if eq(parameters.with_therubyracer, true) }}:
59
- LOAD_THERUBYRACER: 1
60
-
61
- - script: PATH=`dirname $(bundle)`:$PATH CPPFLAGS=$(CPPFLAGS) LDFLAGS=$(LDFLAGS) $(bundle) exec rake compile
62
- displayName: Compile extension
63
-
64
- - script: |
65
- find . -name '*.log' -exec cat '{}' \;
66
- displayName: Print logs
67
- condition: failed()
68
-
69
- - script: $(bundle) exec rake test
70
- displayName: Run tests
71
- env:
72
- ${{ if eq(parameters.with_mini_racer, true) }}:
73
- LOAD_MINI_RACER: 1
74
- ${{ if eq(parameters.with_therubyracer, true) }}:
75
- LOAD_THERUBYRACER: 1
76
-
77
- - ${{ if and(eq(parameters.imageName, 'ubuntu-18.04'), eq(parameters.with_mini_racer, false), eq(parameters.with_therubyracer, false)) }}:
78
- - script: $(bundle) exec rake test:valgrind
79
- displayName: Run tests w/ valgrind
80
-
81
- - script: |
82
- PATH=$PATH:$(dirname $(which $(gem)))
83
- $(bundle) exec rake build
84
- sudo PATH=$PATH $(gem) install pkg/*.gem
85
- displayName: Check that the gem is installable
86
-
87
- - ${{ if eq(parameters.publishCoverage, true) }}:
88
- - bash: >
89
- test -z "$CODECOV_TOKEN" || bash <(curl -s https://codecov.io/bash)
90
- displayName: "Publish coverage (Codecov)"
91
- env:
92
- CODECOV_TOKEN: $(CODECOV_TOKEN)