mini_racer 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: f8218ee18399c771370bf599a4d4cd46707e9f463502e058c98fb38de7505c36
4
+ data.tar.gz: 8fb4a94f36528343c71b05d2b25473a86c02ff0caf4b651acad4be460ea5f016
5
+ SHA512:
6
+ metadata.gz: 6765304fc32d76d8e7050eeed958130e0e2075d7d2826edc6e855eeb447799b5f009d29b87e448f20c1c1cebba583d9d16569d5f0f83d5f1a64e2530333a5cee
7
+ data.tar.gz: b224d6b448e1bc064b051adace85bf7ead7334b7682fe132897e87e028de6506afe5fc1921612ec9b8da3b09232f49cf9a6ecba4e594739792479e6e2fbfa54f
@@ -0,0 +1,11 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ lib/mini_racer_extension.so
11
+ *.bundle
@@ -0,0 +1,17 @@
1
+ language: ruby
2
+ rvm:
3
+ - 2.5
4
+ - 2.6
5
+ - 2.7
6
+ - ruby-head
7
+ matrix:
8
+ include:
9
+ - rvm: 2.5.1
10
+ os: osx
11
+ osx_image: xcode9.4
12
+ dist: trusty
13
+ sudo: true
14
+ before_install:
15
+ - gem update --system
16
+ - gem install bundler -v 1.16.2
17
+ cache: bundler
@@ -0,0 +1,219 @@
1
+ - 22-07-2020
2
+
3
+ - 0.3.0
4
+
5
+ - FEATURE: upgraded to libv8 version 8.4.255.0
6
+
7
+ - 29-06-2020
8
+
9
+ - 0.2.15
10
+
11
+ - FEATURE: basic wasm support via pump_message_loop
12
+
13
+ - 15-05-2020
14
+
15
+ - 0.2.14
16
+
17
+ - FIX: ensure_gc_after_idle should take in milliseconds like the rest of the APIs not seconds
18
+ - FEATURE: strict params on MiniRacer::Context.new
19
+
20
+ - 15-05-2020
21
+
22
+ - 0.2.13
23
+
24
+ - FIX: edge case around ensure_gc_after_idle possibly firing when context is not idle
25
+
26
+ - 15-05-2020
27
+
28
+ - 0.2.12
29
+
30
+ - FEATURE: isolate.low_memory_notification which can force a full GC
31
+ - FEATURE: MiniRacer::Context.new(ensure_gc_after_idle: 2) - to force full GC 2 seconds after context is idle, this allows you to conserve memory on isolates
32
+
33
+ - 14-05-2020
34
+
35
+ - 0.2.11
36
+
37
+ - FIX: dumping heap snapshots was not flushing the file leading to corrupt snapshots
38
+ - FIX: a use-after-free shutdown crash
39
+
40
+ - 0.2.10
41
+
42
+ - 22-04-2020
43
+
44
+ - FEATURE: memory softlimit support for nogvl_context_call
45
+
46
+ - 0.2.9
47
+
48
+ - 09-01-2020
49
+
50
+ - FIX: correct segfault when JS returns a Symbol and properly cast to ruby symbol
51
+
52
+ - 0.2.8
53
+
54
+ - 11-11-2019
55
+
56
+ - FIX: ensure thread live cycle is properly accounter for following file descriptor fix
57
+
58
+ - 0.2.7
59
+
60
+ - 11-11-2019
61
+
62
+ - FIX: release the file descriptor for timeout pipe earlier (this avoids holding too many files open in Ruby 2.7)
63
+
64
+ - 14-05-2019
65
+
66
+ - 0.2.6
67
+
68
+ - FEATURE: add support for write_heap_snapshot which helps you analyze memory
69
+
70
+ - 25-04-2019
71
+
72
+ - 0.2.5
73
+
74
+ - FIX: Compatiblity fixes for V8 7 and above @ignisf
75
+ - FIX: Memory leak in gc_callback @messense
76
+ - IMPROVEMENT: Added example of sourcemap support @ianks
77
+ - URGENT: you will need this release for latest version of libv8 to work
78
+
79
+ - 02-11-2018
80
+
81
+ - 0.2.4
82
+
83
+ - FIX: deadlock releasing context when shared isolates are used
84
+ - FEATURE: include js backtrace when snapshots do not compile
85
+
86
+ - 28-09-2018
87
+
88
+ - 0.2.3
89
+
90
+ - Drop all conditional logic from Mini Racer compilation for clang, always
91
+ rely on MacOS being High Sierra or up
92
+
93
+ - 26-09-2018
94
+
95
+ - 0.2.2
96
+
97
+ - WORKAROUND: RUBY_PLATFORM is hardcoded on Ruby compile and can not be
98
+ trusted for feature detection, use a different technique when checking for
99
+ macOS Mojave
100
+
101
+ - 25-09-2018
102
+
103
+ - 0.2.1
104
+
105
+ - FEATURE: Mojave macOS support
106
+
107
+ - 06-07-2018
108
+
109
+ - 0.2.0
110
+ - FEATURE: context#call to allow for cheaper invocation of functions
111
+ - FIX: rare memory leak when terminating a long running attached function
112
+ - FIX: rare segfault when terminating a long running attached function
113
+ - FIX: Reimplement Isolate#idle_notification using idle_notification_deadline, API remains the same @ignisf
114
+ - Account for changes in the upstream V8 API @ignisf
115
+ - Support for libv8 6.7
116
+
117
+ 23-08-2017
118
+
119
+ - 0.1.15
120
+
121
+ - bump dependency of libv8 to 6.3
122
+
123
+ 23-08-2017
124
+
125
+ - 0.1.14
126
+
127
+ - libv8 erronuously bumped to beta, reverted change
128
+
129
+ 23-08-2017
130
+
131
+ - 0.1.13
132
+
133
+ - Fix: amend array buffer allocator to use v8 6.0 compatible allocator @ignisf
134
+
135
+ 18-07-2017
136
+
137
+ - 0.1.12
138
+
139
+ - Feature: upgrade libv8 to 5.9
140
+ - Fix: warning when runnin with ruby warnings enabled (missed @disposed initialize)
141
+
142
+ 18-07-2017
143
+
144
+ - 0.1.11
145
+
146
+ - Feature: upgrade libv8 to 5.7
147
+
148
+ 13-07-2017
149
+
150
+ - 0.1.10
151
+
152
+ - Fix leak: memory leak when disposing a context (20 bytes per context)
153
+ - Feature: added #heap_stats so you can get visibility from context to actual memory usage of isolate
154
+ - Feature: added #dispose so you reclaim all v8 memory right away as opposed to waiting for GC
155
+ - Feature: you can now specify filename in an eval eg: eval('a = 1', filename: 'my_awesome.js')
156
+
157
+ 09-03-2017
158
+
159
+ - 0.1.9
160
+
161
+ - Perf: speed up ruby/node boundary performance when moving large objects
162
+
163
+ 06-02-2017
164
+
165
+ - 0.1.8
166
+
167
+ - Fix: Include math.h to fix use of undeclared identifier floor with rbx. See #51
168
+
169
+ 02-11-2016
170
+
171
+ - 0.1.7
172
+
173
+ - Fix: if for some reason an isolate was forked don't free it and raise a warning instead to avoid hanging process
174
+
175
+ 25-10-2016
176
+
177
+ - 0.1.6
178
+
179
+ - Fix: timeout behavior was incorrect, in some cases stop could be called on already stopped contexts
180
+
181
+ 10-10-2016
182
+
183
+ - 0.1.5
184
+
185
+ - Support for snapshots, shared isolates, runtime flags thanks to @wk8
186
+ - Fix timeout behavior when it occurs in an attached Ruby method
187
+
188
+ 19-05-2016
189
+
190
+ - 0.1.4
191
+
192
+ - Set upper bound for libv8 inclusion @ignisf
193
+ - Support conversion of Date, Time and DateTime from Ruby to JS @seanmakesgames
194
+ - Support conversion of large numbers back from Ruby to JS @seanmakesgames
195
+
196
+ - 0.1.3
197
+
198
+ - Support more conversions from Ruby back to JS (Hash, Symbol, Array)
199
+ - Support attaching nested objects
200
+
201
+
202
+ 17-05-2016
203
+
204
+ - 0.1.2
205
+
206
+ - Gemspec specifies minimal version of Ruby (2.0)
207
+ - Implement #load on Context to load files
208
+
209
+ 17-05-2016
210
+
211
+ - 0.1.1
212
+
213
+ - Added unblock function so SIGINT does not lead to a crash
214
+
215
+ 14-05-2016
216
+
217
+ - 0.1.1.beta.1
218
+
219
+ - First release
@@ -0,0 +1,49 @@
1
+ # Contributor Code of Conduct
2
+
3
+ As contributors and maintainers of this project, and in the interest of
4
+ fostering an open and welcoming community, we pledge to respect all people who
5
+ contribute through reporting issues, posting feature requests, updating
6
+ documentation, submitting pull requests or patches, and other activities.
7
+
8
+ We are committed to making participation in this project a harassment-free
9
+ experience for everyone, regardless of level of experience, gender, gender
10
+ identity and expression, sexual orientation, disability, personal appearance,
11
+ body size, race, ethnicity, age, religion, or nationality.
12
+
13
+ Examples of unacceptable behavior by participants include:
14
+
15
+ * The use of sexualized language or imagery
16
+ * Personal attacks
17
+ * Trolling or insulting/derogatory comments
18
+ * Public or private harassment
19
+ * Publishing other's private information, such as physical or electronic
20
+ addresses, without explicit permission
21
+ * Other unethical or unprofessional conduct
22
+
23
+ Project maintainers have the right and responsibility to remove, edit, or
24
+ reject comments, commits, code, wiki edits, issues, and other contributions
25
+ that are not aligned to this Code of Conduct, or to ban temporarily or
26
+ permanently any contributor for other behaviors that they deem inappropriate,
27
+ threatening, offensive, or harmful.
28
+
29
+ By adopting this Code of Conduct, project maintainers commit themselves to
30
+ fairly and consistently applying these principles to every aspect of managing
31
+ this project. Project maintainers who do not follow or enforce the Code of
32
+ Conduct may be permanently removed from the project team.
33
+
34
+ This code of conduct applies both within project spaces and in public spaces
35
+ when an individual is representing the project or its community.
36
+
37
+ Instances of abusive, harassing, or otherwise unacceptable behavior may be
38
+ reported by contacting a project maintainer at sam.saffron@gmail.com. All
39
+ complaints will be reviewed and investigated and will result in a response that
40
+ is deemed necessary and appropriate to the circumstances. Maintainers are
41
+ obligated to maintain confidentiality with regard to the reporter of an
42
+ incident.
43
+
44
+ This Code of Conduct is adapted from the [Contributor Covenant][homepage],
45
+ version 1.3.0, available at
46
+ [http://contributor-covenant.org/version/1/3/0/][version]
47
+
48
+ [homepage]: http://contributor-covenant.org
49
+ [version]: http://contributor-covenant.org/version/1/3/0/
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in mini_racer.gemspec
4
+ gemspec
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2016-2019, the mini_racer project authors.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in
13
+ all copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
+ THE SOFTWARE.
@@ -0,0 +1,471 @@
1
+ # MiniRacer
2
+
3
+ [![Build Status](https://travis-ci.org/rubyjs/mini_racer.svg?branch=master)](https://travis-ci.org/rubyjs/mini_racer)
4
+
5
+ Minimal, modern embedded V8 for Ruby.
6
+
7
+ MiniRacer provides a minimal two way bridge between the V8 JavaScript engine and Ruby.
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.
10
+
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
+
13
+ ### A note about Ruby version Support
14
+
15
+ MiniRacer only supports non-EOL versions of Ruby. See [Ruby](https://www.ruby-lang.org/en/downloads) to see the list of non-EOL Rubies.
16
+
17
+ If you require support for older versions of Ruby install an older version of the gem.
18
+
19
+ ## Features
20
+
21
+ ### Simple eval for JavaScript
22
+
23
+ You can simply eval one or many JavaScript snippets in a shared context
24
+
25
+ ```ruby
26
+ context = MiniRacer::Context.new
27
+ context.eval 'var adder = (a,b)=>a+b;'
28
+ puts context.eval 'adder(20,22)'
29
+ # => 42
30
+ ```
31
+
32
+ ### Attach global Ruby functions to your JavaScript context
33
+
34
+ You can attach one or many ruby proc that can be accessed via JavaScript
35
+
36
+ ```ruby
37
+ context = MiniRacer::Context.new
38
+ context.attach("math.adder", proc{|a,b| a+b})
39
+ puts context.eval 'math.adder(20,22)'
40
+ # => 42
41
+ ```
42
+
43
+ ```ruby
44
+ context = MiniRacer::Context.new
45
+ context.attach("array_and_hash", proc{{a: 1, b: [1, {a: 1}]}})
46
+ puts context.eval 'array_and_hash()'
47
+ # => {"a" => 1, "b" => [1, {"a" => 1}]}
48
+ ```
49
+
50
+ ### GIL free JavaScript execution
51
+
52
+ The Ruby Global interpreter lock is released when scripts are executing
53
+
54
+ ```ruby
55
+ context = MiniRacer::Context.new
56
+ Thread.new do
57
+ sleep 1
58
+ context.stop
59
+ end
60
+ context.eval 'while(true){}'
61
+ # => exception is raised
62
+ ```
63
+
64
+ This allows you to execute multiple scripts in parallel.
65
+
66
+ ### Timeout support
67
+
68
+ Contexts can specify a default timeout for scripts
69
+
70
+ ```ruby
71
+ # times out after 1 second (1000 ms)
72
+ context = MiniRacer::Context.new(timeout: 1000)
73
+ context.eval 'while(true){}'
74
+ # => exception is raised
75
+ ```
76
+
77
+ ### Memory softlimit support
78
+
79
+ Contexts can specify a memory softlimit for scripts
80
+
81
+ ```ruby
82
+ # terminates script if heap usage exceeds 200mb after V8 garbage collection has run
83
+ context = MiniRacer::Context.new(max_memory: 200000000)
84
+ context.eval 'var a = new Array(10000); while(true) {a = a.concat(new Array(10000)); print("loop " + a.length);}'
85
+ # => V8OutOfMemoryError is raised
86
+ ```
87
+
88
+ ### Rich debugging with "filename" support
89
+
90
+ ```ruby
91
+
92
+ context = MiniRacer::Context.new
93
+ context.eval('var foo = function() {bar();}', filename: 'a/foo.js')
94
+ context.eval('bar()', filename: 'a/bar.js')
95
+
96
+ # MiniRacer::RuntimeError is raised containing the filenames you specified for evals in backtrace
97
+
98
+ ```
99
+
100
+ ### Fork safety
101
+
102
+ Some Ruby web servers employ forking (for example unicorn or puma in clustered mode). V8 is not fork safe.
103
+ Sadly Ruby does not have support for fork notifications per [#5446](https://bugs.ruby-lang.org/issues/5446).
104
+
105
+ If you want to ensure your application does not leak memory after fork either:
106
+
107
+ 1. Ensure no MiniRacer::Context objects are created in the master process
108
+
109
+ Or
110
+
111
+ 2. Dispose manually of all MiniRacer::Context objects prior to forking
112
+
113
+ ```ruby
114
+ # before fork
115
+
116
+ require 'objspace'
117
+ ObjectSpace.each_object(MiniRacer::Context){|c| c.dispose}
118
+
119
+ # fork here
120
+ ```
121
+
122
+ ### Threadsafe
123
+
124
+ Context usage is threadsafe
125
+
126
+ ```ruby
127
+
128
+ context = MiniRacer::Context.new
129
+ context.eval('counter=0; plus=()=>counter++;')
130
+
131
+ (1..10).map do
132
+ Thread.new {
133
+ context.eval("plus()")
134
+ }
135
+ end.each(&:join)
136
+
137
+ puts context.eval("counter")
138
+ # => 10
139
+
140
+ ```
141
+
142
+ ### Snapshots
143
+
144
+ Contexts can be created with pre-loaded snapshots:
145
+
146
+ ```ruby
147
+
148
+ snapshot = MiniRacer::Snapshot.new('function hello() { return "world!"; }')
149
+
150
+ context = MiniRacer::Context.new(snapshot: snapshot)
151
+
152
+ context.eval("hello()")
153
+ # => "world!"
154
+
155
+ ```
156
+
157
+ 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:
158
+
159
+ ```
160
+ There is an important limitation to snapshots: they can only capture V8’s
161
+ heap. Any interaction from V8 with the outside is off-limits when creating the
162
+ snapshot. Such interactions include:
163
+
164
+ * defining and calling API callbacks (i.e. functions created via v8::FunctionTemplate)
165
+ * creating typed arrays, since the backing store may be allocated outside of V8
166
+
167
+ And of course, values derived from sources such as `Math.random` or `Date.now`
168
+ are fixed once the snapshot has been captured. They are no longer really random
169
+ nor reflect the current time.
170
+ ```
171
+
172
+ 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:
173
+
174
+ ```ruby
175
+
176
+ snapshot = MiniRacer::Snapshot.new('var counter = 0; function hello() { counter++; return "world! "; }')
177
+
178
+ snapshot.warmup!('hello()')
179
+
180
+ context = MiniRacer::Context.new(snapshot: snapshot)
181
+
182
+ context.eval('hello()')
183
+ # => "world! 1"
184
+ context.eval('counter')
185
+ # => 1
186
+
187
+ ```
188
+
189
+ ### Shared isolates
190
+
191
+ By default, MiniRacer's contexts each have their own isolate (V8 runtime). For efficiency, it is possible to re-use an isolate across contexts:
192
+
193
+ ```ruby
194
+
195
+ isolate = MiniRacer::Isolate.new
196
+
197
+ context1 = MiniRacer::Context.new(isolate: isolate)
198
+ context2 = MiniRacer::Context.new(isolate: isolate)
199
+
200
+ context1.isolate == context2.isolate
201
+ # => true
202
+ ```
203
+
204
+ The main benefit of this is avoiding creating/destroying isolates when not needed (for example if you use a lot of contexts).
205
+
206
+ The caveat with this is that a given isolate can only execute one context at a time, so don't share isolates across contexts that you want to run concurrently.
207
+
208
+ 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:
209
+
210
+ ```ruby
211
+ snapshot = MiniRacer::Snapshot.new('function hello() { return "world!"; }')
212
+
213
+ isolate = MiniRacer::Isolate.new(snapshot)
214
+
215
+ context = MiniRacer::Context.new(isolate: isolate)
216
+
217
+ context.eval("hello()")
218
+ # => "world!"
219
+ ```
220
+
221
+ Re-using the same isolate over and over again means V8's garbage collector will have to run to clean it up every now and then; it's possible to trigger a _blocking_ V8 GC run inside your isolate by running the `idle_notification` method on it, which takes a single argument: the amount of time (in milliseconds) that V8 should use at most for garbage collecting:
222
+
223
+ ```ruby
224
+ isolate = MiniRacer::Isolate.new
225
+
226
+ context = MiniRacer::Context.new(isolate: isolate)
227
+
228
+ # do stuff with that context...
229
+
230
+ # give up to 100ms for V8 garbage collection
231
+ isolate.idle_notification(100)
232
+
233
+ # force V8 to perform a full GC
234
+ isolate.low_memory_notification
235
+
236
+ ```
237
+
238
+ This can come in handy to force V8 GC runs for example in between requests if you use MiniRacer on a web application.
239
+
240
+ Note that this method maps directly to [`v8::Isolate::IdleNotification`](http://bespin.cz/~ondras/html/classv8_1_1Isolate.html#aea16cbb2e351de9a3ae7be2b7cb48297), and that in particular its return value is the same (true if there is no further garbage to collect, false otherwise) and the same caveats apply, in particular that `there is no guarantee that the [call will return] within the time limit.`
241
+
242
+ Additionally you may automate this process on a context by defining it with `MiniRacer::Content.new(ensure_gc_after_idle: 1000)`. Using this will ensure V8 will run a full GC using `context.isolate.low_memory_notification` 1 second after the last eval on the context. Low memory notification is both slower and more aggressive than an idle_notification and will ensure long living isolates use minimal amounts of memory.
243
+
244
+ ### V8 Runtime flags
245
+
246
+ It is possible to set V8 Runtime flags:
247
+
248
+ ```ruby
249
+ MiniRacer::Platform.set_flags! :noconcurrent_recompilation, max_inlining_levels: 10
250
+ ```
251
+
252
+ This can come in handy if you want to use MiniRacer with Unicorn, which doesn't seem to alwatys appreciate V8's liberal use of threading:
253
+ ```ruby
254
+ MiniRacer::Platform.set_flags! :noconcurrent_recompilation, :noconcurrent_sweeping
255
+ ```
256
+
257
+ Or else to unlock experimental features in V8, for example tail recursion optimization:
258
+ ```ruby
259
+ MiniRacer::Platform.set_flags! :harmony
260
+
261
+ js = <<-JS
262
+ 'use strict';
263
+ var f = function f(n){
264
+ if (n <= 0) {
265
+ return 'foo';
266
+ }
267
+ return f(n - 1);
268
+ }
269
+
270
+ f(1e6);
271
+ JS
272
+
273
+ context = MiniRacer::Context.new
274
+
275
+ context.eval js
276
+ # => "foo"
277
+ ```
278
+ The same code without the harmony runtime flag results in a `MiniRacer::RuntimeError: RangeError: Maximum call stack size exceeded` exception.
279
+ Please refer to http://node.green/ as a reference on other harmony features.
280
+
281
+ A list of all V8 runtime flags can be found using `node --v8-options`, or else by perusing [the V8 source code for flags (make sure to use the right version of V8)](https://github.com/v8/v8/blob/master/src/flags/flag-definitions.h).
282
+
283
+ Note that runtime flags must be set before any other operation (e.g. creating a context, a snapshot or an isolate), otherwise an exception will be thrown.
284
+
285
+ Flags:
286
+
287
+ - :expose_gc : Will expose `gc()` which you can run in JavaScript to issue a gc
288
+ - :max_old_space_size : defaults to 1400 (megs) on 64 bit, you can restric memory usage by limiting this.
289
+ - **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.
290
+
291
+ ## Controlling memory
292
+
293
+ When hosting v8 you may want to keep track of memory usage, use #heap_stats to get memory usage:
294
+
295
+ ```ruby
296
+ context = MiniRacer::Context.new(timeout: 5)
297
+ context.eval("let a='testing';")
298
+ p context.heap_stats
299
+ # {:total_physical_size=>1280640,
300
+ # :total_heap_size_executable=>4194304,
301
+ # :total_heap_size=>3100672,
302
+ # :used_heap_size=>1205376,
303
+ # :heap_size_limit=>1501560832}
304
+ ```
305
+
306
+ If you wish to dispose of a context before waiting on the GC use
307
+
308
+ ```ruby
309
+ context = MiniRacer::Context.new(timeout: 5)
310
+ context.eval("let a='testing';")
311
+ context.dispose
312
+ context.eval("a = 2")
313
+ # MiniRacer::ContextDisposedError
314
+
315
+ # nothing works on the context from now on, its a shell waiting to be disposed
316
+ ```
317
+
318
+ A MiniRacer context can also be dumped in a heapsnapshot file using `#write_heap_snapshot(file_or_io)`
319
+
320
+ ```ruby
321
+ context = MiniRacer::Context.new(timeout: 5)
322
+ context.eval("let a='testing';")
323
+ context.write_heap_snapshot("test.heapsnapshot")
324
+ ```
325
+
326
+ This file can then be loaded in the memory tab of the chrome dev console.
327
+
328
+ ### Function call
329
+
330
+ This calls the function passed as first argument:
331
+
332
+ ```ruby
333
+ context = MiniRacer::Context.new
334
+ context.eval('function hello(name) { return "Hello, " + name + "!" }')
335
+ context.call('hello', 'George')
336
+ # "Hello, George!"
337
+ ```
338
+
339
+ Performance is slightly better than running `eval('hello("George")')` since:
340
+
341
+ - compilation of eval'd string is avoided
342
+ - function arguments don't need to be converted to JSON
343
+
344
+ ## Performance
345
+
346
+ The `bench` folder contains benchmark.
347
+
348
+ ### Benchmark minification of Discourse application.js (both minified and unminified)
349
+
350
+ MiniRacer outperforms node when minifying assets via execjs.
351
+
352
+ - MiniRacer version 0.1.9
353
+ - node version 6.10
354
+ - therubyracer version 0.12.2
355
+
356
+ ```
357
+
358
+ $ bundle exec ruby bench.rb mini_racer
359
+ Benching with mini_racer
360
+ mini_racer minify discourse_app.js 9292.72063ms
361
+ mini_racer minify discourse_app_minified.js 11799.850171ms
362
+ mini_racer minify discourse_app.js twice (2 threads) 10269.570797ms
363
+
364
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb node
365
+ Benching with node
366
+ node minify discourse_app.js 13302.715484ms
367
+ node minify discourse_app_minified.js 18100.761243ms
368
+ node minify discourse_app.js twice (2 threads) 14383.600207000001ms
369
+
370
+ sam@ubuntu exec_js_uglify % bundle exec ruby bench.rb therubyracer
371
+ Benching with therubyracer
372
+ therubyracer minify discourse_app.js 171683.01867700001ms
373
+ therubyracer minify discourse_app_minified.js 143138.88492ms
374
+ therubyracer minify discourse_app.js twice (2 threads) NEVER FINISH
375
+
376
+ Killed: 9
377
+ ```
378
+
379
+ The huge performance disparity (MiniRacer is 10x faster) is due to MiniRacer running latest version of V8. In July 2016 there is a queued upgrade to therubyracer which should bring some of the perf inline.
380
+
381
+ Note how the global interpreter lock release leads to 2 threads doing the same work taking the same wall time as 1 thread.
382
+
383
+ As a rule MiniRacer strives to always support and depend on the latest stable version of libv8.
384
+
385
+ ## Source Maps
386
+
387
+ 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.
388
+
389
+ ## Installation
390
+
391
+ Add this line to your application's Gemfile:
392
+
393
+ ```ruby
394
+ gem 'mini_racer'
395
+ ```
396
+
397
+ And then execute:
398
+
399
+ $ bundle
400
+
401
+ Or install it yourself as:
402
+
403
+ $ gem install mini_racer
404
+
405
+
406
+ **Note** using v8.h and compiling MiniRacer requires a C++11 standard compiler, more specifically clang 3.5 (or later) or gcc 4.8 (or later).
407
+
408
+
409
+ ## Travis-ci
410
+
411
+ To install `mini-racer` you will need a version of gcc that supports C++11 (gcc 4.8) this is included by default in ubuntu trusty based images.
412
+
413
+ 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 4.8 on precise the simpler approach is to opt for the trusty based image.
414
+
415
+ Add this to your .travis.yml file:
416
+
417
+ ```
418
+ - sudo: required
419
+ - dist: trusty
420
+ ```
421
+
422
+ ## Similar Projects
423
+
424
+ ### therubyracer
425
+
426
+ - https://github.com/cowboyd/therubyracer
427
+ - Most comprehensive bridge available
428
+ - Provides the ability to "eval" JavaScript
429
+ - Provides the ability to invoke Ruby code from JavaScript
430
+ - Hold references to JavaScript objects and methods in your Ruby code
431
+ - Hold references to Ruby objects and methods in JavaScript code
432
+ - Uses libv8, so installation is fast
433
+ - Supports timeouts for JavaScript execution
434
+ - Does not release global interpreter lock, so performance is constrained to a single thread
435
+ - Currently (May 2016) only supports v8 version 3.16.14 (Released approx November 2013), plans to upgrade by July 2016
436
+ - Supports execjs
437
+
438
+
439
+ ### v8eval
440
+
441
+ - https://github.com/sony/v8eval
442
+ - Provides the ability to "eval" JavaScript using the latest V8 engine
443
+ - 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.
444
+ - Does not release global interpreter lock when executing JavaScript
445
+ - Does not allow you to invoke Ruby code from JavaScript
446
+ - Multi runtime support due to SWIG based bindings
447
+ - Supports a JavaScript debugger
448
+ - Does not support timeouts for JavaScript execution
449
+ - No support for execjs (can not be used with Rails uglifier and coffeescript gems)
450
+
451
+
452
+ ### therubyrhino
453
+
454
+ - https://github.com/cowboyd/therubyrhino
455
+ - API compatible with therubyracer
456
+ - Uses Mozilla's Rhino engine https://github.com/mozilla/rhino
457
+ - Requires JRuby
458
+ - Support for timeouts for JavaScript execution
459
+ - Concurrent cause .... JRuby
460
+ - Supports execjs
461
+
462
+
463
+ ## Contributing
464
+
465
+ 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.
466
+
467
+
468
+ ## License
469
+
470
+ The gem is available as open source under the terms of the [MIT License](http://opensource.org/licenses/MIT).
471
+