sq_mini_racer 0.2.4.0.2 → 0.2.5.0.1.beta1

Sign up to get free protection for your applications and to get access to all the features.
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)