mini_racer 0.21.3 → 0.22.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.
@@ -4,9 +4,8 @@
4
4
  # Maybe one day it can be actually shared again between both backends.
5
5
 
6
6
  module MiniRacer
7
-
8
- MARSHAL_STACKDEPTH_DEFAULT = 2**9-2
9
- MARSHAL_STACKDEPTH_MAX_VALUE = 2**10-2
7
+ MARSHAL_STACKDEPTH_DEFAULT = (2**9) - 2
8
+ MARSHAL_STACKDEPTH_MAX_VALUE = (2**10) - 2
10
9
 
11
10
  class FailedV8Conversion
12
11
  attr_reader :info
@@ -25,7 +24,8 @@ module MiniRacer
25
24
  class Isolate
26
25
  def initialize(snapshot = nil)
27
26
  unless snapshot.nil? || snapshot.is_a?(Snapshot)
28
- raise ArgumentError, "snapshot must be a Snapshot object, passed a #{snapshot.inspect}"
27
+ raise ArgumentError,
28
+ "snapshot must be a Snapshot object, passed a #{snapshot.inspect}"
29
29
  end
30
30
 
31
31
  # defined in the C class
@@ -51,12 +51,10 @@ module MiniRacer
51
51
  # normalize flags to strings, and adds leading dashes if needed
52
52
  def flag_to_string(flag)
53
53
  if flag.is_a?(Hash)
54
- flag.map do |key, value|
55
- "#{flag_to_string(key)} #{value}"
56
- end
54
+ flag.map { |key, value| "#{flag_to_string(key)} #{value}" }
57
55
  else
58
56
  str = flag.to_s
59
- str = "--#{str}" unless str.start_with?('--')
57
+ str = "--#{str}" unless str.start_with?("--")
60
58
  str
61
59
  end
62
60
  end
@@ -65,13 +63,12 @@ module MiniRacer
65
63
 
66
64
  # eval is defined in the C class
67
65
  class Context
68
-
69
66
  class ExternalFunction
70
67
  def initialize(name, callback, parent)
71
68
  unless String === name
72
69
  raise ArgumentError, "parent_object must be a String"
73
70
  end
74
- parent_object, _ , @name = name.rpartition(".")
71
+ parent_object, _, @name = name.rpartition(".")
75
72
  @callback = callback
76
73
  @parent = parent
77
74
  @parent_object_eval = nil
@@ -83,26 +80,40 @@ module MiniRacer
83
80
  @parent_object_eval = ""
84
81
  prev = ""
85
82
  first = true
86
- parent_object.split(".").each do |obj|
87
- prev << obj
88
- if first
89
- @parent_object_eval << "if (typeof #{prev} !== 'object' || typeof #{prev} !== 'function') { #{prev} = {} };\n"
90
- else
91
- @parent_object_eval << "#{prev} = #{prev} || {};\n"
83
+ parent_object
84
+ .split(".")
85
+ .each do |obj|
86
+ prev << obj
87
+ if first
88
+ @parent_object_eval << "if (typeof #{prev} !== 'object' || typeof #{prev} !== 'function') { #{prev} = {} };\n"
89
+ else
90
+ @parent_object_eval << "#{prev} = #{prev} || {};\n"
91
+ end
92
+ prev << "."
93
+ first = false
92
94
  end
93
- prev << "."
94
- first = false
95
- end
96
95
  @parent_object_eval << "#{parent_object};"
97
96
  end
98
97
  notify_v8
99
98
  end
100
99
  end
101
100
 
102
- def initialize(max_memory: nil, timeout: nil, isolate: nil, ensure_gc_after_idle: nil, snapshot: nil, marshal_stack_depth: nil)
103
- options ||= {}
104
-
105
- check_init_options!(isolate: isolate, snapshot: snapshot, max_memory: max_memory, marshal_stack_depth: marshal_stack_depth, ensure_gc_after_idle: ensure_gc_after_idle, timeout: timeout)
101
+ def initialize(
102
+ max_memory: nil,
103
+ timeout: nil,
104
+ isolate: nil,
105
+ ensure_gc_after_idle: nil,
106
+ snapshot: nil,
107
+ marshal_stack_depth: nil
108
+ )
109
+ check_init_options!(
110
+ isolate: isolate,
111
+ snapshot: snapshot,
112
+ max_memory: max_memory,
113
+ marshal_stack_depth: marshal_stack_depth,
114
+ ensure_gc_after_idle: ensure_gc_after_idle,
115
+ timeout: timeout
116
+ )
106
117
 
107
118
  @functions = {}
108
119
  @timeout = nil
@@ -140,17 +151,20 @@ module MiniRacer
140
151
  @isolate = create_isolate_value
141
152
  end
142
153
 
143
- def eval(str, options=nil)
144
- raise(ContextDisposedError, 'attempted to call eval on a disposed context!') if @disposed
154
+ def eval(str, options = nil)
155
+ if @disposed
156
+ raise(
157
+ ContextDisposedError,
158
+ "attempted to call eval on a disposed context!"
159
+ )
160
+ end
145
161
 
146
162
  filename = options && options[:filename].to_s
147
163
 
148
164
  @eval_thread = Thread.current
149
165
  isolate_mutex.synchronize do
150
166
  @current_exception = nil
151
- timeout do
152
- eval_unsafe(str, filename)
153
- end
167
+ timeout { eval_unsafe(str, filename) }
154
168
  end
155
169
  ensure
156
170
  @eval_thread = nil
@@ -158,19 +172,30 @@ module MiniRacer
158
172
  end
159
173
 
160
174
  def call(function_name, *arguments)
161
- raise(ContextDisposedError, 'attempted to call function on a disposed context!') if @disposed
175
+ if @disposed
176
+ raise(
177
+ ContextDisposedError,
178
+ "attempted to call function on a disposed context!"
179
+ )
180
+ end
162
181
 
163
182
  @eval_thread = Thread.current
164
183
  isolate_mutex.synchronize do
165
- timeout do
166
- call_unsafe(function_name, *arguments)
167
- end
184
+ timeout { call_unsafe(function_name, *arguments) }
168
185
  end
169
186
  ensure
170
187
  @eval_thread = nil
171
188
  ensure_gc_thread if @ensure_gc_after_idle
172
189
  end
173
190
 
191
+ def eval_await(*, **)
192
+ raise MiniRacer::Error, "eval_await is not supported on TruffleRuby"
193
+ end
194
+
195
+ def call_await(*, **)
196
+ raise MiniRacer::Error, "call_await is not supported on TruffleRuby"
197
+ end
198
+
174
199
  def dispose
175
200
  return if @disposed
176
201
  isolate_mutex.synchronize do
@@ -181,43 +206,36 @@ module MiniRacer
181
206
  end
182
207
  end
183
208
 
184
-
185
209
  def attach(name, callback)
186
- raise(ContextDisposedError, 'attempted to call function on a disposed context!') if @disposed
187
-
188
- wrapped = lambda do |*args|
189
- begin
190
-
191
- r = nil
210
+ if @disposed
211
+ raise(
212
+ ContextDisposedError,
213
+ "attempted to call function on a disposed context!"
214
+ )
215
+ end
192
216
 
217
+ wrapped =
218
+ lambda do |*args|
193
219
  begin
194
- @callback_mutex.synchronize{
195
- @callback_running = true
196
- }
197
- r = callback.call(*args)
198
- ensure
199
- @callback_mutex.synchronize{
200
- @callback_running = false
201
- }
202
- end
220
+ r = nil
203
221
 
204
- # wait up to 2 seconds for this to be interrupted
205
- # will very rarely be called cause #raise is called
206
- # in another mutex
207
- @callback_mutex.synchronize {
208
- if @thread_raise_called
209
- sleep 2
222
+ begin
223
+ @callback_mutex.synchronize { @callback_running = true }
224
+ r = callback.call(*args)
225
+ ensure
226
+ @callback_mutex.synchronize { @callback_running = false }
210
227
  end
211
- }
212
228
 
213
- r
229
+ # wait up to 2 seconds for this to be interrupted
230
+ # will very rarely be called cause #raise is called
231
+ # in another mutex
232
+ @callback_mutex.synchronize { sleep 2 if @thread_raise_called }
214
233
 
215
- ensure
216
- @callback_mutex.synchronize {
217
- @thread_raise_called = false
218
- }
234
+ r
235
+ ensure
236
+ @callback_mutex.synchronize { @thread_raise_called = false }
237
+ end
219
238
  end
220
- end
221
239
 
222
240
  isolate_mutex.synchronize do
223
241
  external = ExternalFunction.new(name, wrapped, self)
@@ -232,41 +250,43 @@ module MiniRacer
232
250
  @ensure_gc_mutex.synchronize do
233
251
  @ensure_gc_thread = nil if !@ensure_gc_thread&.alive?
234
252
  return if !Thread.main.alive? # avoid "can't alloc thread" exception
235
- @ensure_gc_thread ||= Thread.new do
236
- ensure_gc_after_idle_seconds = @ensure_gc_after_idle / 1000.0
237
- done = false
238
- while !done
239
- now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
240
-
241
- if @disposed
242
- @ensure_gc_thread = nil
243
- break
244
- end
253
+ @ensure_gc_thread ||=
254
+ Thread.new do
255
+ ensure_gc_after_idle_seconds = @ensure_gc_after_idle / 1000.0
256
+ done = false
257
+ while !done
258
+ now = Process.clock_gettime(Process::CLOCK_MONOTONIC)
259
+
260
+ if @disposed
261
+ @ensure_gc_thread = nil
262
+ break
263
+ end
245
264
 
246
- if !@eval_thread && ensure_gc_after_idle_seconds < now - @last_eval
247
- @ensure_gc_mutex.synchronize do
248
- isolate_mutex.synchronize do
249
- if !@eval_thread
250
- low_memory_notification if !@disposed
251
- @ensure_gc_thread = nil
252
- done = true
265
+ if !@eval_thread &&
266
+ ensure_gc_after_idle_seconds < now - @last_eval
267
+ @ensure_gc_mutex.synchronize do
268
+ isolate_mutex.synchronize do
269
+ if !@eval_thread
270
+ low_memory_notification if !@disposed
271
+ @ensure_gc_thread = nil
272
+ done = true
273
+ end
253
274
  end
254
275
  end
255
276
  end
277
+ sleep ensure_gc_after_idle_seconds if !done
256
278
  end
257
- sleep ensure_gc_after_idle_seconds if !done
258
279
  end
259
- end
260
280
  end
261
281
  end
262
282
 
263
283
  def stop_attached
264
- @callback_mutex.synchronize{
284
+ @callback_mutex.synchronize do
265
285
  if @callback_running
266
286
  @eval_thread.raise ScriptTerminatedError, "Terminated during callback"
267
287
  @thread_raise_called = true
268
288
  end
269
- }
289
+ end
270
290
  end
271
291
 
272
292
  def timeout(&blk)
@@ -275,26 +295,21 @@ module MiniRacer
275
295
  mutex = Mutex.new
276
296
  done = false
277
297
 
278
- rp,wp = IO.pipe
298
+ rp, wp = IO.pipe
279
299
 
280
- t = Thread.new do
281
- begin
282
- result = rp.wait_readable(@timeout/1000.0)
283
- if !result
284
- mutex.synchronize do
285
- stop unless done
286
- end
300
+ t =
301
+ Thread.new do
302
+ begin
303
+ result = rp.wait_readable(@timeout / 1000.0)
304
+ mutex.synchronize { stop unless done } if !result
305
+ rescue => e
306
+ STDERR.puts e
307
+ STDERR.puts "FAILED TO TERMINATE DUE TO TIMEOUT"
287
308
  end
288
- rescue => e
289
- STDERR.puts e
290
- STDERR.puts "FAILED TO TERMINATE DUE TO TIMEOUT"
291
309
  end
292
- end
293
310
 
294
311
  rval = blk.call
295
- mutex.synchronize do
296
- done = true
297
- end
312
+ mutex.synchronize { done = true }
298
313
 
299
314
  wp.close
300
315
 
@@ -310,44 +325,69 @@ module MiniRacer
310
325
  rp&.close
311
326
  end
312
327
 
313
- def check_init_options!(isolate:, snapshot:, max_memory:, marshal_stack_depth:, ensure_gc_after_idle:, timeout:)
314
- assert_option_is_nil_or_a('isolate', isolate, Isolate)
315
- assert_option_is_nil_or_a('snapshot', snapshot, Snapshot)
316
-
317
- assert_numeric_or_nil('max_memory', max_memory, min_value: 10_000, max_value: 2**32-1)
318
- assert_numeric_or_nil('marshal_stack_depth', marshal_stack_depth, min_value: 1, max_value: MARSHAL_STACKDEPTH_MAX_VALUE)
319
- assert_numeric_or_nil('ensure_gc_after_idle', ensure_gc_after_idle, min_value: 1)
320
- assert_numeric_or_nil('timeout', timeout, min_value: 1)
328
+ def check_init_options!(
329
+ isolate:,
330
+ snapshot:,
331
+ max_memory:,
332
+ marshal_stack_depth:,
333
+ ensure_gc_after_idle:,
334
+ timeout:
335
+ )
336
+ assert_option_is_nil_or_a("isolate", isolate, Isolate)
337
+ assert_option_is_nil_or_a("snapshot", snapshot, Snapshot)
338
+
339
+ assert_numeric_or_nil(
340
+ "max_memory",
341
+ max_memory,
342
+ min_value: 10_000,
343
+ max_value: (2**32) - 1
344
+ )
345
+ assert_numeric_or_nil(
346
+ "marshal_stack_depth",
347
+ marshal_stack_depth,
348
+ min_value: 1,
349
+ max_value: MARSHAL_STACKDEPTH_MAX_VALUE
350
+ )
351
+ assert_numeric_or_nil(
352
+ "ensure_gc_after_idle",
353
+ ensure_gc_after_idle,
354
+ min_value: 1
355
+ )
356
+ assert_numeric_or_nil("timeout", timeout, min_value: 1)
321
357
 
322
358
  if isolate && snapshot
323
- raise ArgumentError, 'can only pass one of isolate and snapshot options'
359
+ raise ArgumentError, "can only pass one of isolate and snapshot options"
324
360
  end
325
361
  end
326
362
 
327
363
  def assert_numeric_or_nil(option_name, object, min_value:, max_value: nil)
328
364
  if max_value && object.is_a?(Numeric) && object > max_value
329
- raise ArgumentError, "#{option_name} must be less than or equal to #{max_value}"
365
+ raise ArgumentError,
366
+ "#{option_name} must be less than or equal to #{max_value}"
330
367
  end
331
368
 
332
369
  if object.is_a?(Numeric) && object < min_value
333
- raise ArgumentError, "#{option_name} must be larger than or equal to #{min_value}"
370
+ raise ArgumentError,
371
+ "#{option_name} must be larger than or equal to #{min_value}"
334
372
  end
335
373
 
336
374
  if !object.nil? && !object.is_a?(Numeric)
337
- raise ArgumentError, "#{option_name} must be a number, passed a #{object.inspect}"
375
+ raise ArgumentError,
376
+ "#{option_name} must be a number, passed a #{object.inspect}"
338
377
  end
339
378
  end
340
379
 
341
380
  def assert_option_is_nil_or_a(option_name, object, klass)
342
381
  unless object.nil? || object.is_a?(klass)
343
- raise ArgumentError, "#{option_name} must be a #{klass} object, passed a #{object.inspect}"
382
+ raise ArgumentError,
383
+ "#{option_name} must be a #{klass} object, passed a #{object.inspect}"
344
384
  end
345
385
  end
346
386
  end
347
387
 
348
388
  # `size` and `warmup!` public methods are defined in the C class
349
389
  class Snapshot
350
- def initialize(str = '')
390
+ def initialize(str = "")
351
391
  # ensure it first can load
352
392
  begin
353
393
  ctx = MiniRacer::Context.new