mini_racer 0.6.2 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG +74 -115
- data/README.md +122 -134
- data/ext/mini_racer_extension/extconf.rb +9 -0
- data/ext/mini_racer_extension/mini_racer_extension.cc +28 -66
- data/ext/mini_racer_loader/extconf.rb +5 -0
- data/lib/mini_racer/truffleruby.rb +355 -0
- data/lib/mini_racer/version.rb +2 -2
- data/lib/mini_racer.rb +19 -17
- data/lib/mini_racer_extension.so +4 -0
- data/lib/mini_racer_loader.so +0 -0
- metadata +12 -19
- data/.dockerignore +0 -12
- data/.github/workflows/ci.yml +0 -78
- data/.gitignore +0 -13
- data/.travis.yml +0 -23
- data/Dockerfile +0 -21
- data/Gemfile +0 -4
- data/Rakefile +0 -96
- data/bin/console +0 -14
- data/bin/setup +0 -8
- data/mini_racer.gemspec +0 -39
data/README.md
CHANGED
|
@@ -1,20 +1,30 @@
|
|
|
1
1
|
# MiniRacer
|
|
2
2
|
|
|
3
|
-
[](https://github.com/rubyjs/mini_racer/actions/workflows/ci.yml) 
|
|
4
4
|
|
|
5
5
|
Minimal, modern embedded V8 for Ruby.
|
|
6
6
|
|
|
7
7
|
MiniRacer provides a minimal two way bridge between the V8 JavaScript engine and Ruby.
|
|
8
8
|
|
|
9
|
-
It was created as an alternative to the excellent [therubyracer](https://github.com/cowboyd/therubyracer). Unlike therubyracer, mini_racer only implements a minimal bridge. This reduces the surface area making upgrading v8 much simpler and exhaustive testing simpler.
|
|
9
|
+
It was created as an alternative to the excellent [therubyracer](https://github.com/cowboyd/therubyracer), which is [no longer maintained](https://github.com/rubyjs/therubyracer/issues/462). Unlike therubyracer, mini_racer only implements a minimal bridge. This reduces the surface area making upgrading v8 much simpler and exhaustive testing simpler.
|
|
10
10
|
|
|
11
11
|
MiniRacer has an adapter for [execjs](https://github.com/rails/execjs) so it can be used directly with Rails projects to minify assets, run babel or compile CoffeeScript.
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
## Supported Ruby Versions & Troubleshooting
|
|
14
14
|
|
|
15
|
-
MiniRacer only supports non-EOL versions of Ruby. See [Ruby](https://www.ruby-lang.org/en/downloads)
|
|
15
|
+
MiniRacer only supports non-EOL versions of Ruby. See [Ruby Maintenance Branches](https://www.ruby-lang.org/en/downloads/branches/) for the list of non-EOL Rubies. If you require support for older versions of Ruby install an older version of the gem.
|
|
16
16
|
|
|
17
|
-
|
|
17
|
+
MiniRacer **does not support** [Ruby built on MinGW](https://github.com/rubyjs/mini_racer/issues/252#issuecomment-1201172236), "pure windows" no Cygwin, no WSL2 (see https://github.com/rubyjs/libv8-node/issues/9).
|
|
18
|
+
|
|
19
|
+
If you have a problem installing MiniRacer, please consider the following steps:
|
|
20
|
+
|
|
21
|
+
* make sure you try the latest released version of `mini_racer`
|
|
22
|
+
* make sure you have Rubygems >= 3.2.13 and bundler >= 2.2.13 installed: `gem update --system`
|
|
23
|
+
* if you are using bundler
|
|
24
|
+
* make sure it is actually using the latest bundler version: [`bundle update --bundler`](https://bundler.io/v2.4/man/bundle-update.1.html)
|
|
25
|
+
* make sure to have `PLATFORMS` set correctly in `Gemfile.lock` via [`bundle lock --add-platform`](https://bundler.io/v2.4/man/bundle-lock.1.html#SUPPORTING-OTHER-PLATFORMS)
|
|
26
|
+
* make sure to recompile/reinstall `mini_racer` and `libv8-node` after OS upgrades (for example via `gem uninstall --all mini_racer libv8-node`)
|
|
27
|
+
* make sure you are on the latest patch/teeny version of a supported Ruby branch
|
|
18
28
|
|
|
19
29
|
## Features
|
|
20
30
|
|
|
@@ -24,8 +34,8 @@ You can simply eval one or many JavaScript snippets in a shared context
|
|
|
24
34
|
|
|
25
35
|
```ruby
|
|
26
36
|
context = MiniRacer::Context.new
|
|
27
|
-
context.eval
|
|
28
|
-
puts context.eval
|
|
37
|
+
context.eval("var adder = (a,b)=>a+b;")
|
|
38
|
+
puts context.eval("adder(20,22)")
|
|
29
39
|
# => 42
|
|
30
40
|
```
|
|
31
41
|
|
|
@@ -36,20 +46,20 @@ You can attach one or many ruby proc that can be accessed via JavaScript
|
|
|
36
46
|
```ruby
|
|
37
47
|
context = MiniRacer::Context.new
|
|
38
48
|
context.attach("math.adder", proc{|a,b| a+b})
|
|
39
|
-
puts context.eval
|
|
49
|
+
puts context.eval("math.adder(20,22)")
|
|
40
50
|
# => 42
|
|
41
51
|
```
|
|
42
52
|
|
|
43
53
|
```ruby
|
|
44
54
|
context = MiniRacer::Context.new
|
|
45
55
|
context.attach("array_and_hash", proc{{a: 1, b: [1, {a: 1}]}})
|
|
46
|
-
puts context.eval
|
|
56
|
+
puts context.eval("array_and_hash()")
|
|
47
57
|
# => {"a" => 1, "b" => [1, {"a" => 1}]}
|
|
48
58
|
```
|
|
49
59
|
|
|
50
60
|
### GIL free JavaScript execution
|
|
51
61
|
|
|
52
|
-
The Ruby Global interpreter lock is released when scripts are executing
|
|
62
|
+
The Ruby Global interpreter lock is released when scripts are executing:
|
|
53
63
|
|
|
54
64
|
```ruby
|
|
55
65
|
context = MiniRacer::Context.new
|
|
@@ -57,35 +67,34 @@ Thread.new do
|
|
|
57
67
|
sleep 1
|
|
58
68
|
context.stop
|
|
59
69
|
end
|
|
60
|
-
context.eval
|
|
70
|
+
context.eval("while(true){}")
|
|
61
71
|
# => exception is raised
|
|
62
72
|
```
|
|
63
73
|
|
|
64
74
|
This allows you to execute multiple scripts in parallel.
|
|
65
75
|
|
|
66
|
-
### Timeout
|
|
76
|
+
### Timeout Support
|
|
67
77
|
|
|
68
78
|
Contexts can specify a default timeout for scripts
|
|
69
79
|
|
|
70
80
|
```ruby
|
|
71
|
-
# times out after 1 second (1000 ms)
|
|
72
81
|
context = MiniRacer::Context.new(timeout: 1000)
|
|
73
|
-
context.eval
|
|
74
|
-
# => exception is raised
|
|
82
|
+
context.eval("while(true){}")
|
|
83
|
+
# => exception is raised after 1 second (1000 ms)
|
|
75
84
|
```
|
|
76
85
|
|
|
77
|
-
### Memory softlimit
|
|
86
|
+
### Memory softlimit Support
|
|
78
87
|
|
|
79
88
|
Contexts can specify a memory softlimit for scripts
|
|
80
89
|
|
|
81
90
|
```ruby
|
|
82
91
|
# terminates script if heap usage exceeds 200mb after V8 garbage collection has run
|
|
83
|
-
context = MiniRacer::Context.new(max_memory:
|
|
84
|
-
context.eval
|
|
92
|
+
context = MiniRacer::Context.new(max_memory: 200_000_000)
|
|
93
|
+
context.eval("var a = new Array(10000); while(true) {a = a.concat(new Array(10000)) }")
|
|
85
94
|
# => V8OutOfMemoryError is raised
|
|
86
95
|
```
|
|
87
96
|
|
|
88
|
-
### Object marshal max
|
|
97
|
+
### Object marshal max Stack Ddepth Support
|
|
89
98
|
|
|
90
99
|
Contexts can specify a stack depth limit for object marshalling. Max depth is unbounded by default.
|
|
91
100
|
|
|
@@ -98,35 +107,38 @@ context.eval("let arr = []; arr.push(arr); a(arr)")
|
|
|
98
107
|
# => RuntimeError is raised
|
|
99
108
|
```
|
|
100
109
|
|
|
101
|
-
### Rich
|
|
110
|
+
### Rich Debugging with File Name in Stack Trace Support
|
|
102
111
|
|
|
103
|
-
|
|
112
|
+
You can provide `filename:` to `#eval` which will be used in stack traces produced by V8:
|
|
104
113
|
|
|
114
|
+
```ruby
|
|
105
115
|
context = MiniRacer::Context.new
|
|
106
|
-
context.eval(
|
|
107
|
-
context.eval(
|
|
108
|
-
|
|
109
|
-
# MiniRacer::RuntimeError is raised containing the filenames you specified for evals in backtrace
|
|
116
|
+
context.eval("var foo = function() {bar();}", filename: "a/foo.js")
|
|
117
|
+
context.eval("bar()", filename: "a/bar.js")
|
|
110
118
|
|
|
119
|
+
# JavaScript at a/bar.js:1:1: ReferenceError: bar is not defined (MiniRacer::RuntimeError)
|
|
120
|
+
# …
|
|
111
121
|
```
|
|
112
122
|
|
|
113
|
-
### Fork
|
|
123
|
+
### Fork Safety
|
|
114
124
|
|
|
115
|
-
Some Ruby web servers employ forking (for example unicorn or puma in clustered mode). V8 is not fork safe.
|
|
116
|
-
Sadly Ruby does not have support for fork notifications per [#5446](https://bugs.ruby-lang.org/issues/5446).
|
|
125
|
+
Some Ruby web servers employ forking (for example unicorn or puma in clustered mode). V8 is not fork safe by default and sadly Ruby does not have support for fork notifications per [#5446](https://bugs.ruby-lang.org/issues/5446).
|
|
117
126
|
|
|
118
|
-
|
|
127
|
+
Since 0.6.1 mini_racer does support V8 single threaded platform mode which should remove most forking related issues. To enable run this before using `MiniRacer::Context`, for example in a Rails initializer:
|
|
119
128
|
|
|
120
|
-
|
|
129
|
+
```ruby
|
|
130
|
+
MiniRacer::Platform.set_flags!(:single_threaded)
|
|
131
|
+
```
|
|
121
132
|
|
|
122
|
-
|
|
133
|
+
If you want to ensure your application does not leak memory after fork either:
|
|
123
134
|
|
|
124
|
-
|
|
135
|
+
1. Ensure no `MiniRacer::Context` objects are created in the master process; or
|
|
136
|
+
2. Dispose manually of all `MiniRacer::Context` objects prior to forking
|
|
125
137
|
|
|
126
138
|
```ruby
|
|
127
139
|
# before fork
|
|
128
140
|
|
|
129
|
-
require
|
|
141
|
+
require "objspace"
|
|
130
142
|
ObjectSpace.each_object(MiniRacer::Context){|c| c.dispose}
|
|
131
143
|
|
|
132
144
|
# fork here
|
|
@@ -137,9 +149,8 @@ ObjectSpace.each_object(MiniRacer::Context){|c| c.dispose}
|
|
|
137
149
|
Context usage is threadsafe
|
|
138
150
|
|
|
139
151
|
```ruby
|
|
140
|
-
|
|
141
152
|
context = MiniRacer::Context.new
|
|
142
|
-
context.eval(
|
|
153
|
+
context.eval("counter=0; plus=()=>counter++;")
|
|
143
154
|
|
|
144
155
|
(1..10).map do
|
|
145
156
|
Thread.new {
|
|
@@ -149,7 +160,6 @@ end.each(&:join)
|
|
|
149
160
|
|
|
150
161
|
puts context.eval("counter")
|
|
151
162
|
# => 10
|
|
152
|
-
|
|
153
163
|
```
|
|
154
164
|
|
|
155
165
|
### Snapshots
|
|
@@ -157,46 +167,40 @@ puts context.eval("counter")
|
|
|
157
167
|
Contexts can be created with pre-loaded snapshots:
|
|
158
168
|
|
|
159
169
|
```ruby
|
|
160
|
-
|
|
161
|
-
snapshot = MiniRacer::Snapshot.new('function hello() { return "world!"; }')
|
|
170
|
+
snapshot = MiniRacer::Snapshot.new("function hello() { return 'world!'; }")
|
|
162
171
|
|
|
163
172
|
context = MiniRacer::Context.new(snapshot: snapshot)
|
|
164
173
|
|
|
165
174
|
context.eval("hello()")
|
|
166
175
|
# => "world!"
|
|
167
|
-
|
|
168
|
-
```
|
|
169
|
-
|
|
170
|
-
Snapshots can come in handy for example if you want your contexts to be pre-loaded for effiency. It uses [V8 snapshots](http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html) under the hood; see [this link](http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html) for caveats using these, in particular:
|
|
171
|
-
|
|
172
176
|
```
|
|
173
|
-
There is an important limitation to snapshots: they can only capture V8’s
|
|
174
|
-
heap. Any interaction from V8 with the outside is off-limits when creating the
|
|
175
|
-
snapshot. Such interactions include:
|
|
176
177
|
|
|
177
|
-
|
|
178
|
-
* creating typed arrays, since the backing store may be allocated outside of V8
|
|
178
|
+
Snapshots can come in handy for example if you want your contexts to be pre-loaded for efficiency. It uses [V8 snapshots](http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html) under the hood; see [this link](http://v8project.blogspot.com/2015/09/custom-startup-snapshots.html) for caveats using these, in particular:
|
|
179
179
|
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
180
|
+
> There is an important limitation to snapshots: they can only capture V8’s
|
|
181
|
+
> heap. Any interaction from V8 with the outside is off-limits when creating the
|
|
182
|
+
> snapshot. Such interactions include:
|
|
183
|
+
>
|
|
184
|
+
> * defining and calling API callbacks (i.e. functions created via v8::FunctionTemplate)
|
|
185
|
+
> * creating typed arrays, since the backing store may be allocated outside of V8
|
|
186
|
+
>
|
|
187
|
+
> And of course, values derived from sources such as `Math.random` or `Date.now`
|
|
188
|
+
> are fixed once the snapshot has been captured. They are no longer really random
|
|
189
|
+
> nor reflect the current time.
|
|
184
190
|
|
|
185
191
|
Also note that snapshots can be warmed up, using the `warmup!` method, which allows you to call functions which are otherwise lazily compiled to get them to compile right away; any side effect of your warm up code being then dismissed. [More details on warming up here](https://github.com/electron/electron/issues/169#issuecomment-76783481), and a small example:
|
|
186
192
|
|
|
187
193
|
```ruby
|
|
194
|
+
snapshot = MiniRacer::Snapshot.new("var counter = 0; function hello() { counter++; return 'world! '; }")
|
|
188
195
|
|
|
189
|
-
snapshot
|
|
190
|
-
|
|
191
|
-
snapshot.warmup!('hello()')
|
|
196
|
+
snapshot.warmup!("hello()")
|
|
192
197
|
|
|
193
198
|
context = MiniRacer::Context.new(snapshot: snapshot)
|
|
194
199
|
|
|
195
|
-
context.eval(
|
|
200
|
+
context.eval("hello()")
|
|
196
201
|
# => "world! 1"
|
|
197
|
-
context.eval(
|
|
202
|
+
context.eval("counter")
|
|
198
203
|
# => 1
|
|
199
|
-
|
|
200
204
|
```
|
|
201
205
|
|
|
202
206
|
### Shared isolates
|
|
@@ -204,7 +208,6 @@ context.eval('counter')
|
|
|
204
208
|
By default, MiniRacer's contexts each have their own isolate (V8 runtime). For efficiency, it is possible to re-use an isolate across contexts:
|
|
205
209
|
|
|
206
210
|
```ruby
|
|
207
|
-
|
|
208
211
|
isolate = MiniRacer::Isolate.new
|
|
209
212
|
|
|
210
213
|
context1 = MiniRacer::Context.new(isolate: isolate)
|
|
@@ -221,7 +224,7 @@ The caveat with this is that a given isolate can only execute one context at a t
|
|
|
221
224
|
Also, note that if you want to use shared isolates together with snapshots, you need to first create an isolate with that snapshot, and then create contexts from that isolate:
|
|
222
225
|
|
|
223
226
|
```ruby
|
|
224
|
-
snapshot = MiniRacer::Snapshot.new(
|
|
227
|
+
snapshot = MiniRacer::Snapshot.new("function hello() { return 'world!'; }")
|
|
225
228
|
|
|
226
229
|
isolate = MiniRacer::Isolate.new(snapshot)
|
|
227
230
|
|
|
@@ -245,7 +248,6 @@ isolate.idle_notification(100)
|
|
|
245
248
|
|
|
246
249
|
# force V8 to perform a full GC
|
|
247
250
|
isolate.low_memory_notification
|
|
248
|
-
|
|
249
251
|
```
|
|
250
252
|
|
|
251
253
|
This can come in handy to force V8 GC runs for example in between requests if you use MiniRacer on a web application.
|
|
@@ -263,11 +265,13 @@ MiniRacer::Platform.set_flags! :noconcurrent_recompilation, max_inlining_levels:
|
|
|
263
265
|
```
|
|
264
266
|
|
|
265
267
|
This can come in handy if you want to use MiniRacer with Unicorn, which doesn't seem to always appreciate V8's liberal use of threading:
|
|
268
|
+
|
|
266
269
|
```ruby
|
|
267
270
|
MiniRacer::Platform.set_flags! :noconcurrent_recompilation, :noconcurrent_sweeping
|
|
268
271
|
```
|
|
269
272
|
|
|
270
273
|
Or else to unlock experimental features in V8, for example tail recursion optimization:
|
|
274
|
+
|
|
271
275
|
```ruby
|
|
272
276
|
MiniRacer::Platform.set_flags! :harmony
|
|
273
277
|
|
|
@@ -288,6 +292,7 @@ context = MiniRacer::Context.new
|
|
|
288
292
|
context.eval js
|
|
289
293
|
# => "foo"
|
|
290
294
|
```
|
|
295
|
+
|
|
291
296
|
The same code without the harmony runtime flag results in a `MiniRacer::RuntimeError: RangeError: Maximum call stack size exceeded` exception.
|
|
292
297
|
Please refer to http://node.green/ as a reference on other harmony features.
|
|
293
298
|
|
|
@@ -297,17 +302,18 @@ Note that runtime flags must be set before any other operation (e.g. creating a
|
|
|
297
302
|
|
|
298
303
|
Flags:
|
|
299
304
|
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
305
|
+
* `:expose_gc`: Will expose `gc()` which you can run in JavaScript to issue a GC run.
|
|
306
|
+
* `:max_old_space_size`: defaults to 1400 (megs) on 64 bit, you can restrict memory usage by limiting this.
|
|
307
|
+
|
|
308
|
+
**NOTE TO READER** our documentation could be awesome we could be properly documenting all the flags, they are hugely useful, if you feel like documenting a few more, PLEASE DO, PRs are welcome.
|
|
303
309
|
|
|
304
310
|
## Controlling memory
|
|
305
311
|
|
|
306
|
-
When hosting v8 you may want to keep track of memory usage, use
|
|
312
|
+
When hosting v8 you may want to keep track of memory usage, use `#heap_stats` to get memory usage:
|
|
307
313
|
|
|
308
314
|
```ruby
|
|
309
|
-
context = MiniRacer::Context.new
|
|
310
|
-
context
|
|
315
|
+
context = MiniRacer::Context.new
|
|
316
|
+
# use context
|
|
311
317
|
p context.heap_stats
|
|
312
318
|
# {:total_physical_size=>1280640,
|
|
313
319
|
# :total_heap_size_executable=>4194304,
|
|
@@ -316,27 +322,27 @@ p context.heap_stats
|
|
|
316
322
|
# :heap_size_limit=>1501560832}
|
|
317
323
|
```
|
|
318
324
|
|
|
319
|
-
If you wish to dispose of a context before waiting on the GC use
|
|
325
|
+
If you wish to dispose of a context before waiting on the GC use `#dispose`:
|
|
320
326
|
|
|
321
327
|
```ruby
|
|
322
|
-
context = MiniRacer::Context.new
|
|
328
|
+
context = MiniRacer::Context.new
|
|
323
329
|
context.eval("let a='testing';")
|
|
324
330
|
context.dispose
|
|
325
331
|
context.eval("a = 2")
|
|
326
332
|
# MiniRacer::ContextDisposedError
|
|
327
333
|
|
|
328
|
-
# nothing works on the context from now on,
|
|
334
|
+
# nothing works on the context from now on, it's a shell waiting to be disposed
|
|
329
335
|
```
|
|
330
336
|
|
|
331
337
|
A MiniRacer context can also be dumped in a heapsnapshot file using `#write_heap_snapshot(file_or_io)`
|
|
332
338
|
|
|
333
339
|
```ruby
|
|
334
|
-
context = MiniRacer::Context.new
|
|
335
|
-
context
|
|
340
|
+
context = MiniRacer::Context.new
|
|
341
|
+
# use context
|
|
336
342
|
context.write_heap_snapshot("test.heapsnapshot")
|
|
337
343
|
```
|
|
338
344
|
|
|
339
|
-
This file can then be loaded in the memory tab of the
|
|
345
|
+
This file can then be loaded in the "memory" tab of the [Chrome DevTools](https://developer.chrome.com/docs/devtools/memory-problems/heap-snapshots/#view_snapshots).
|
|
340
346
|
|
|
341
347
|
### Function call
|
|
342
348
|
|
|
@@ -344,30 +350,29 @@ This calls the function passed as first argument:
|
|
|
344
350
|
|
|
345
351
|
```ruby
|
|
346
352
|
context = MiniRacer::Context.new
|
|
347
|
-
context.eval(
|
|
348
|
-
context.call(
|
|
353
|
+
context.eval("function hello(name) { return `Hello, ${name}!` }")
|
|
354
|
+
context.call("hello", "George")
|
|
349
355
|
# "Hello, George!"
|
|
350
356
|
```
|
|
351
357
|
|
|
352
|
-
Performance is slightly better than running `eval(
|
|
358
|
+
Performance is slightly better than running `context.eval("hello('George')")` since:
|
|
353
359
|
|
|
354
|
-
|
|
355
|
-
|
|
360
|
+
* compilation of eval'd string is avoided
|
|
361
|
+
* function arguments don't need to be converted to JSON
|
|
356
362
|
|
|
357
363
|
## Performance
|
|
358
364
|
|
|
359
365
|
The `bench` folder contains benchmark.
|
|
360
366
|
|
|
361
|
-
### Benchmark minification of Discourse application.js (both minified and
|
|
367
|
+
### Benchmark minification of Discourse application.js (both minified and non-minified)
|
|
362
368
|
|
|
363
369
|
MiniRacer outperforms node when minifying assets via execjs.
|
|
364
370
|
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
```
|
|
371
|
+
* MiniRacer version 0.1.9
|
|
372
|
+
* node version 6.10
|
|
373
|
+
* therubyracer version 0.12.2
|
|
370
374
|
|
|
375
|
+
```terminal
|
|
371
376
|
$ bundle exec ruby bench.rb mini_racer
|
|
372
377
|
Benching with mini_racer
|
|
373
378
|
mini_racer minify discourse_app.js 9292.72063ms
|
|
@@ -404,81 +409,64 @@ MiniRacer can fully support source maps but must be configured correctly to do s
|
|
|
404
409
|
Add this line to your application's Gemfile:
|
|
405
410
|
|
|
406
411
|
```ruby
|
|
407
|
-
gem
|
|
412
|
+
gem "mini_racer"
|
|
408
413
|
```
|
|
409
414
|
|
|
410
415
|
And then execute:
|
|
411
416
|
|
|
412
|
-
|
|
417
|
+
```terminal
|
|
418
|
+
$ bundle
|
|
413
419
|
|
|
414
420
|
Or install it yourself as:
|
|
415
421
|
|
|
416
|
-
|
|
417
|
-
|
|
422
|
+
```terminal
|
|
423
|
+
$ gem install mini_racer
|
|
424
|
+
```
|
|
418
425
|
|
|
419
426
|
**Note** using v8.h and compiling MiniRacer requires a C++11 standard compiler, more specifically clang 3.5 (or later) or GCC 6.3 (or later).
|
|
420
427
|
|
|
421
|
-
|
|
422
|
-
## Travis-ci
|
|
423
|
-
|
|
424
|
-
To install `mini-racer` you will need a version of GCC that supports C++11 (GCC 6.3) this is included by default in ubuntu trusty based images.
|
|
425
|
-
|
|
426
|
-
Travis today ships by default with a precise based image. Precise Pangolin (12.04 LTS) was first released in August 2012. Even though you can install GCC 6.3 on precise the simpler approach is to opt for the trusty based image.
|
|
427
|
-
|
|
428
|
-
Add this to your .travis.yml file:
|
|
429
|
-
|
|
430
|
-
```
|
|
431
|
-
- sudo: required
|
|
432
|
-
- dist: trusty
|
|
433
|
-
```
|
|
434
|
-
|
|
435
428
|
## Similar Projects
|
|
436
429
|
|
|
437
430
|
### therubyracer
|
|
438
431
|
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
432
|
+
* https://github.com/cowboyd/therubyracer
|
|
433
|
+
* Most comprehensive bridge available
|
|
434
|
+
* Provides the ability to "eval" JavaScript
|
|
435
|
+
* Provides the ability to invoke Ruby code from JavaScript
|
|
436
|
+
* Hold references to JavaScript objects and methods in your Ruby code
|
|
437
|
+
* Hold references to Ruby objects and methods in JavaScript code
|
|
438
|
+
* Uses libv8, so installation is fast
|
|
439
|
+
* Supports timeouts for JavaScript execution
|
|
440
|
+
* Does not release global interpreter lock, so performance is constrained to a single thread
|
|
441
|
+
* Currently (May 2016) only supports v8 version 3.16.14 (Released approx November 2013), plans to upgrade by July 2016
|
|
442
|
+
* Supports execjs
|
|
451
443
|
|
|
452
444
|
### v8eval
|
|
453
445
|
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
446
|
+
* https://github.com/sony/v8eval
|
|
447
|
+
* Provides the ability to "eval" JavaScript using the latest V8 engine
|
|
448
|
+
* Does not depend on the [libv8](https://github.com/cowboyd/libv8) gem, installation can take 10-20 mins as V8 needs to be downloaded and compiled.
|
|
449
|
+
* Does not release global interpreter lock when executing JavaScript
|
|
450
|
+
* Does not allow you to invoke Ruby code from JavaScript
|
|
451
|
+
* Multi runtime support due to SWIG based bindings
|
|
452
|
+
* Supports a JavaScript debugger
|
|
453
|
+
* Does not support timeouts for JavaScript execution
|
|
454
|
+
* No support for execjs (can not be used with Rails uglifier and coffeescript gems)
|
|
464
455
|
|
|
465
456
|
### therubyrhino
|
|
466
457
|
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
458
|
+
* https://github.com/cowboyd/therubyrhino
|
|
459
|
+
* API compatible with therubyracer
|
|
460
|
+
* Uses Mozilla's Rhino engine https://github.com/mozilla/rhino
|
|
461
|
+
* Requires JRuby
|
|
462
|
+
* Support for timeouts for JavaScript execution
|
|
463
|
+
* Concurrent cause .... JRuby
|
|
464
|
+
* Supports execjs
|
|
475
465
|
|
|
476
466
|
## Contributing
|
|
477
467
|
|
|
478
468
|
Bug reports and pull requests are welcome on GitHub at https://github.com/rubyjs/mini_racer. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
|
|
479
469
|
|
|
480
|
-
|
|
481
470
|
## License
|
|
482
471
|
|
|
483
472
|
The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
|
|
484
|
-
|
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
require 'mkmf'
|
|
2
|
+
|
|
3
|
+
if RUBY_ENGINE == "truffleruby"
|
|
4
|
+
File.write("Makefile", dummy_makefile($srcdir).join(""))
|
|
5
|
+
return
|
|
6
|
+
end
|
|
7
|
+
|
|
2
8
|
require_relative '../../lib/mini_racer/version'
|
|
3
9
|
gem 'libv8-node', MiniRacer::LIBV8_NODE_VERSION
|
|
4
10
|
require 'libv8-node'
|
|
@@ -70,6 +76,9 @@ end
|
|
|
70
76
|
|
|
71
77
|
Libv8::Node.configure_makefile
|
|
72
78
|
|
|
79
|
+
# --exclude-libs is only for i386 PE and ELF targeted ports
|
|
80
|
+
append_ldflags("-Wl,--exclude-libs=ALL ")
|
|
81
|
+
|
|
73
82
|
if enable_config('asan')
|
|
74
83
|
$CXXFLAGS.insert(0, " -fsanitize=address ")
|
|
75
84
|
$LDFLAGS.insert(0, " -fsanitize=address ")
|