execjs 2.7.0 → 2.9.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c281240b821b63764b2972d440a39405d77bca30
4
- data.tar.gz: f661c8d78fb1099bc3787e29c40b91b2e067be2e
2
+ SHA256:
3
+ metadata.gz: 2cff0ab13dcd1bc38d12b1ca38d99773ba123ad75573c8b8f4789232677df308
4
+ data.tar.gz: a84d80b533fa677491bdb26d28bfedd44443deb5ff772d9eeb7db7e9e0d0ab36
5
5
  SHA512:
6
- metadata.gz: d59815bb2b71498baa84e75f9ccdc5210e82a5dc474f22a1c9b749602eeee91a4e0844484e7580c05cee6dcfa94c6672b72e6e2133c23227e9d5011af3110632
7
- data.tar.gz: e38d3bfdfe65de9017d2ba829e40646c98c931d9fae56f8aa39cb345ce5da3e39a4b1c7199fa79dc89609f56d8afae24427d22ef64f67fba092456f60e8f4632
6
+ metadata.gz: fbac63f192c113786e7df0bce663a0e40a241b54534e01f18047d356d7ccb1514e4aeb8a610a336f85271def9b5956404091caccf6f0c984a20a723f67a364ce
7
+ data.tar.gz: 2f6dfe9ff9154500ea26a0c94a829eacb8b63ac84744791eff8f0b8643182f30118b1f1ed42f08486a4cc05c4e61c0cb8d800df53dcbccdbba5dadb786027b7a
data/README.md CHANGED
@@ -7,17 +7,17 @@ returns the result to you as a Ruby object.
7
7
 
8
8
  ExecJS supports these runtimes:
9
9
 
10
- * [therubyracer](https://github.com/cowboyd/therubyracer) - Google V8
11
- embedded within Ruby
12
10
  * [therubyrhino](https://github.com/cowboyd/therubyrhino) - Mozilla
13
11
  Rhino embedded within JRuby
14
12
  * [Duktape.rb](https://github.com/judofyr/duktape.rb) - Duktape JavaScript interpreter
15
13
  * [Node.js](http://nodejs.org/)
14
+ * [Bun.sh](https://bun.sh) - JavaScript runtime & toolkit designed for speed
16
15
  * Apple JavaScriptCore - Included with Mac OS X
17
16
  * [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) (JScript)
18
17
  * [Google V8](http://code.google.com/p/v8/)
19
- * [mini_racer](https://github.com/discourse/mini_racer) - Google V8
18
+ * [mini_racer](https://github.com/rubyjs/mini_racer) - Google V8
20
19
  embedded within Ruby
20
+ * [GraalVM JavaScript](https://www.graalvm.org/javascript/) - used on TruffleRuby
21
21
 
22
22
  A short example:
23
23
 
@@ -39,6 +39,22 @@ context.call("CoffeeScript.compile", "square = (x) -> x * x", bare: true)
39
39
  # => "var square;\nsquare = function(x) {\n return x * x;\n};"
40
40
  ```
41
41
 
42
+ # Forcing a specific runtime
43
+
44
+ If you'd like to use a specific runtime rather than the autodected one, you can assign `ExecJS.runtime`:
45
+
46
+ ```ruby
47
+ ExecJS.runtime = ExecJS::Runtimes::Node
48
+ ```
49
+
50
+ Alternatively, you can define it via the `EXECJS_RUNTIME` environment variable:
51
+
52
+ ```bash
53
+ EXECJS_RUNTIME=Node ruby ...
54
+ ```
55
+
56
+ You can find the list of possible runtimes in [`lib/execjs/runtimes.rb`](https://github.com/rails/execjs/blob/master/lib/execjs/runtimes.rb).
57
+
42
58
  # Installation
43
59
 
44
60
  ```
@@ -76,7 +92,7 @@ You shouldn't use `ExecJS.eval` on any inputs you wouldn't feel comfortable Ruby
76
92
 
77
93
  ## Contributing to ExecJS
78
94
 
79
- ExecJS is work of hundreds of contributors. You're encouraged to submit pull requests, propose
95
+ ExecJS is work of dozens of contributors. You're encouraged to submit pull requests, propose
80
96
  features and discuss issues.
81
97
 
82
98
  See [CONTRIBUTING](CONTRIBUTING.md).
@@ -6,27 +6,28 @@ module ExecJS
6
6
  class Context < Runtime::Context
7
7
  def initialize(runtime, source = "", options = {})
8
8
  @ctx = Duktape::Context.new(complex_object: nil)
9
- @ctx.exec_string(encode(source), '(execjs)')
9
+ @ctx.exec_string(source.encode(Encoding::UTF_8), '(execjs)')
10
10
  rescue Exception => e
11
11
  raise wrap_error(e)
12
12
  end
13
13
 
14
14
  def exec(source, options = {})
15
15
  return unless /\S/ =~ source
16
- @ctx.eval_string("(function(){#{encode(source)}})()", '(execjs)')
16
+ @ctx.eval_string("(function(){#{source.encode(Encoding::UTF_8)}})()", '(execjs)')
17
17
  rescue Exception => e
18
18
  raise wrap_error(e)
19
19
  end
20
20
 
21
21
  def eval(source, options = {})
22
22
  return unless /\S/ =~ source
23
- @ctx.eval_string("(#{encode(source)})", '(execjs)')
23
+ @ctx.eval_string("(#{source.encode(Encoding::UTF_8)})", '(execjs)')
24
24
  rescue Exception => e
25
25
  raise wrap_error(e)
26
26
  end
27
27
 
28
28
  def call(identifier, *args)
29
- @ctx.call_prop(identifier.split("."), *args)
29
+ @ctx.exec_string("__execjs_duktape_call = #{identifier}", '(execjs)')
30
+ @ctx.call_prop("__execjs_duktape_call", *args)
30
31
  rescue Exception => e
31
32
  raise wrap_error(e)
32
33
  end
@@ -1,11 +1,12 @@
1
- require "tmpdir"
2
1
  require "execjs/runtime"
2
+ require "tmpdir"
3
+ require "json"
3
4
 
4
5
  module ExecJS
5
6
  class ExternalRuntime < Runtime
6
7
  class Context < Runtime::Context
7
8
  def initialize(runtime, source = "", options = {})
8
- source = encode(source)
9
+ source = source.encode(Encoding::UTF_8)
9
10
 
10
11
  @runtime = runtime
11
12
  @source = source
@@ -15,7 +16,7 @@ module ExecJS
15
16
  end
16
17
 
17
18
  def eval(source, options = {})
18
- source = encode(source)
19
+ source = source.encode(Encoding::UTF_8)
19
20
 
20
21
  if /\S/ =~ source
21
22
  exec("return eval(#{::JSON.generate("(#{source})", quirks_mode: true)})")
@@ -23,7 +24,7 @@ module ExecJS
23
24
  end
24
25
 
25
26
  def exec(source, options = {})
26
- source = encode(source)
27
+ source = source.encode(Encoding::UTF_8)
27
28
  source = "#{@source}\n#{source}" if @source != ""
28
29
  source = @runtime.compile_source(source)
29
30
 
@@ -77,7 +78,7 @@ module ExecJS
77
78
  .sub(filename, "(execjs)")
78
79
  .strip
79
80
  end
80
- stack.reject! { |line| ["eval code", "eval@[native code]"].include?(line) }
81
+ stack.reject! { |line| ["eval code", "eval code@", "eval@[native code]"].include?(line) }
81
82
  stack.shift unless stack[0].to_s.include?("(execjs)")
82
83
  error_class = value =~ /SyntaxError:/ ? RuntimeError : ProgramError
83
84
  error = error_class.new(value)
@@ -102,7 +103,13 @@ module ExecJS
102
103
  @popen_options[:internal_encoding] = ::Encoding.default_internal || 'UTF-8'
103
104
 
104
105
  if @runner_path
105
- instance_eval generate_compile_method(@runner_path)
106
+ instance_eval <<~RUBY, __FILE__, __LINE__
107
+ def compile_source(source)
108
+ <<-RUNNER
109
+ #{IO.read(@runner_path)}
110
+ RUNNER
111
+ end
112
+ RUBY
106
113
  end
107
114
  end
108
115
 
@@ -142,15 +149,6 @@ module ExecJS
142
149
  end
143
150
 
144
151
  protected
145
- def generate_compile_method(path)
146
- <<-RUBY
147
- def compile_source(source)
148
- <<-RUNNER
149
- #{IO.read(path)}
150
- RUNNER
151
- end
152
- RUBY
153
- end
154
152
 
155
153
  def json2_source
156
154
  @json2_source ||= IO.read(ExecJS.root + "/support/json2.js")
@@ -173,7 +171,7 @@ module ExecJS
173
171
  begin
174
172
  command = binary.split(" ") << filename
175
173
  `#{shell_escape(*command)} 2>&1 > #{path}`
176
- output = File.open(path, 'rb', @popen_options) { |f| f.read }
174
+ output = File.open(path, 'rb', **@popen_options) { |f| f.read }
177
175
  ensure
178
176
  File.unlink(path) if path
179
177
  end
@@ -196,8 +194,8 @@ module ExecJS
196
194
  require 'shellwords'
197
195
 
198
196
  def exec_runtime(filename)
199
- command = "#{Shellwords.join(binary.split(' ') << filename)} 2>&1"
200
- io = IO.popen(command, @popen_options)
197
+ command = "#{Shellwords.join(binary.split(' ') << filename)}"
198
+ io = IO.popen(command, **@popen_options)
201
199
  output = io.read
202
200
  io.close
203
201
 
@@ -209,7 +207,7 @@ module ExecJS
209
207
  end
210
208
  else
211
209
  def exec_runtime(filename)
212
- io = IO.popen(binary.split(' ') << filename, @popen_options.merge({err: [:child, :out]}))
210
+ io = IO.popen(binary.split(' ') << filename, **@popen_options)
213
211
  output = io.read
214
212
  io.close
215
213
 
@@ -0,0 +1,147 @@
1
+ require "execjs/runtime"
2
+
3
+ module ExecJS
4
+ class GraalJSRuntime < Runtime
5
+ class Context < Runtime::Context
6
+ def initialize(runtime, source = "", options = {})
7
+ @context = Polyglot::InnerContext.new
8
+ @context.eval('js', 'delete this.console')
9
+ @js_object = @context.eval('js', 'Object')
10
+
11
+ source = source.encode(Encoding::UTF_8)
12
+ unless source.empty?
13
+ translate do
14
+ eval_in_context(source)
15
+ end
16
+ end
17
+ end
18
+
19
+ def exec(source, options = {})
20
+ source = source.encode(Encoding::UTF_8)
21
+ source = "(function(){#{source}})()" if /\S/.match?(source)
22
+
23
+ translate do
24
+ eval_in_context(source)
25
+ end
26
+ end
27
+
28
+ def eval(source, options = {})
29
+ source = source.encode(Encoding::UTF_8)
30
+ source = "(#{source})" if /\S/.match?(source)
31
+
32
+ translate do
33
+ eval_in_context(source)
34
+ end
35
+ end
36
+
37
+ def call(source, *args)
38
+ source = source.encode(Encoding::UTF_8)
39
+ source = "(#{source})" if /\S/.match?(source)
40
+
41
+ translate do
42
+ function = eval_in_context(source)
43
+ function.call(*convert_ruby_to_js(args))
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ ForeignException = defined?(Polyglot::ForeignException) ? Polyglot::ForeignException : ::RuntimeError
50
+
51
+ def translate
52
+ convert_js_to_ruby yield
53
+ rescue ForeignException => e
54
+ if e.message && e.message.start_with?('SyntaxError:')
55
+ error_class = ExecJS::RuntimeError
56
+ else
57
+ error_class = ExecJS::ProgramError
58
+ end
59
+
60
+ backtrace = (e.backtrace || []).map { |line| line.sub('(eval)', '(execjs)') }
61
+ raise error_class, e.message, backtrace
62
+ end
63
+
64
+ def convert_js_to_ruby(value)
65
+ case value
66
+ when true, false, Integer, Float
67
+ value
68
+ else
69
+ if value.nil?
70
+ nil
71
+ elsif value.respond_to?(:call)
72
+ nil
73
+ elsif value.respond_to?(:to_str)
74
+ value.to_str
75
+ elsif value.respond_to?(:to_ary)
76
+ value.to_ary.map do |e|
77
+ if e.respond_to?(:call)
78
+ nil
79
+ else
80
+ convert_js_to_ruby(e)
81
+ end
82
+ end
83
+ else
84
+ object = value
85
+ h = {}
86
+ object.instance_variables.each do |member|
87
+ v = object[member]
88
+ unless v.respond_to?(:call)
89
+ h[member.to_s] = convert_js_to_ruby(v)
90
+ end
91
+ end
92
+ h
93
+ end
94
+ end
95
+ end
96
+
97
+ def convert_ruby_to_js(value)
98
+ case value
99
+ when nil, true, false, Integer, Float
100
+ value
101
+ when String, Symbol
102
+ Truffle::Interop.as_truffle_string value
103
+ when Array
104
+ value.map { |e| convert_ruby_to_js(e) }
105
+ when Hash
106
+ h = @js_object.new
107
+ value.each_pair do |k,v|
108
+ h[convert_ruby_to_js(k)] = convert_ruby_to_js(v)
109
+ end
110
+ h
111
+ else
112
+ raise TypeError, "Unknown how to convert to JS: #{value.inspect}"
113
+ end
114
+ end
115
+
116
+ class_eval <<-'RUBY', "(execjs)", 1
117
+ def eval_in_context(code); @context.eval('js', code); end
118
+ RUBY
119
+ end
120
+
121
+ def name
122
+ "GraalVM (Graal.js)"
123
+ end
124
+
125
+ def available?
126
+ return @available if defined?(@available)
127
+
128
+ unless RUBY_ENGINE == "truffleruby"
129
+ return @available = false
130
+ end
131
+
132
+ unless defined?(Polyglot::InnerContext)
133
+ warn "TruffleRuby #{RUBY_ENGINE_VERSION} does not have support for inner contexts, use a more recent version", uplevel: 0 if $VERBOSE
134
+ return @available = false
135
+ end
136
+
137
+ unless Polyglot.languages.include? "js"
138
+ warn "The language 'js' is not available, you likely need to `export TRUFFLERUBYOPT='--jvm --polyglot'`", uplevel: 0 if $VERBOSE
139
+ warn "You also need to install the 'js' component with 'gu install js' on GraalVM 22.2+", uplevel: 0 if $VERBOSE
140
+ warn "Note that you need TruffleRuby+GraalVM and not just the TruffleRuby standalone to use #{self.class}", uplevel: 0 if $VERBOSE
141
+ return @available = false
142
+ end
143
+
144
+ @available = true
145
+ end
146
+ end
147
+ end
@@ -4,15 +4,16 @@ module ExecJS
4
4
  class MiniRacerRuntime < Runtime
5
5
  class Context < Runtime::Context
6
6
  def initialize(runtime, source = "", options={})
7
- source = encode(source)
7
+ source = source.encode(Encoding::UTF_8)
8
8
  @context = ::MiniRacer::Context.new
9
+ @context.eval("delete this.console");
9
10
  translate do
10
11
  @context.eval(source)
11
12
  end
12
13
  end
13
14
 
14
15
  def exec(source, options = {})
15
- source = encode(source)
16
+ source = source.encode(Encoding::UTF_8)
16
17
 
17
18
  if /\S/ =~ source
18
19
  eval "(function(){#{source}})()"
@@ -20,7 +21,7 @@ module ExecJS
20
21
  end
21
22
 
22
23
  def eval(source, options = {})
23
- source = encode(source)
24
+ source = source.encode(Encoding::UTF_8)
24
25
 
25
26
  if /\S/ =~ source
26
27
  translate do
@@ -1,10 +1,11 @@
1
1
  require "execjs/runtime"
2
+ require "json"
2
3
 
3
4
  module ExecJS
4
5
  class RubyRhinoRuntime < Runtime
5
6
  class Context < Runtime::Context
6
7
  def initialize(runtime, source = "", options = {})
7
- source = encode(source)
8
+ source = source.encode(Encoding::UTF_8)
8
9
 
9
10
  @rhino_context = ::Rhino::Context.new
10
11
  fix_memory_limit! @rhino_context
@@ -14,7 +15,7 @@ module ExecJS
14
15
  end
15
16
 
16
17
  def exec(source, options = {})
17
- source = encode(source)
18
+ source = source.encode(Encoding::UTF_8)
18
19
 
19
20
  if /\S/ =~ source
20
21
  eval "(function(){#{source}})()", options
@@ -22,7 +23,7 @@ module ExecJS
22
23
  end
23
24
 
24
25
  def eval(source, options = {})
25
- source = encode(source)
26
+ source = source.encode(Encoding::UTF_8)
26
27
 
27
28
  if /\S/ =~ source
28
29
  unbox @rhino_context.eval("(#{source})")
@@ -32,7 +33,11 @@ module ExecJS
32
33
  end
33
34
 
34
35
  def call(properties, *args)
35
- unbox @rhino_context.eval(properties).call(*args)
36
+ # Might no longer be necessary if therubyrhino handles Symbols directly:
37
+ # https://github.com/rubyjs/therubyrhino/issues/43
38
+ converted_args = JSON.parse(JSON.generate(args), create_additions: false)
39
+
40
+ unbox @rhino_context.eval(properties).call(*converted_args)
36
41
  rescue Exception => e
37
42
  raise wrap_error(e)
38
43
  end
@@ -1,23 +1,34 @@
1
- require "execjs/encoding"
2
-
3
1
  module ExecJS
4
2
  # Abstract base class for runtimes
5
3
  class Runtime
6
4
  class Context
7
- include Encoding
8
-
9
5
  def initialize(runtime, source = "", options = {})
10
6
  end
11
7
 
8
+ # Evaluates the +source+ in the context of a function body and returns the
9
+ # returned value.
10
+ #
11
+ # context.exec("return 1") # => 1
12
+ # context.exec("1") # => nil (nothing was returned)
12
13
  def exec(source, options = {})
13
14
  raise NotImplementedError
14
15
  end
15
16
 
17
+ # Evaluates the +source+ as an expression and returns the result.
18
+ #
19
+ # context.eval("1") # => 1
20
+ # context.eval("return 1") # => Raises SyntaxError
16
21
  def eval(source, options = {})
17
22
  raise NotImplementedError
18
23
  end
19
24
 
20
- def call(properties, *args)
25
+ # Evaluates +source+ as an expression (which should be of type
26
+ # +function+), and calls the function with the given arguments.
27
+ # The function will be evaluated with the global object as +this+.
28
+ #
29
+ # context.call("function(a, b) { return a + b }", 1, 1) # => 2
30
+ # context.call("CoffeeScript.compile", "1 + 1")
31
+ def call(source, *args)
21
32
  raise NotImplementedError
22
33
  end
23
34
  end
@@ -2,9 +2,9 @@ require "execjs/module"
2
2
  require "execjs/disabled_runtime"
3
3
  require "execjs/duktape_runtime"
4
4
  require "execjs/external_runtime"
5
- require "execjs/ruby_racer_runtime"
6
5
  require "execjs/ruby_rhino_runtime"
7
6
  require "execjs/mini_racer_runtime"
7
+ require "execjs/graaljs_runtime"
8
8
 
9
9
  module ExecJS
10
10
  module Runtimes
@@ -12,22 +12,32 @@ module ExecJS
12
12
 
13
13
  Duktape = DuktapeRuntime.new
14
14
 
15
- RubyRacer = RubyRacerRuntime.new
16
-
17
15
  RubyRhino = RubyRhinoRuntime.new
18
16
 
17
+ GraalJS = GraalJSRuntime.new
18
+
19
19
  MiniRacer = MiniRacerRuntime.new
20
20
 
21
21
  Node = ExternalRuntime.new(
22
22
  name: "Node.js (V8)",
23
- command: ["nodejs", "node"],
23
+ command: ["node", "nodejs"],
24
24
  runner_path: ExecJS.root + "/support/node_runner.js",
25
25
  encoding: 'UTF-8'
26
26
  )
27
27
 
28
+ Bun = ExternalRuntime.new(
29
+ name: "Bun.sh",
30
+ command: ["bun"],
31
+ runner_path: ExecJS.root + "/support/bun_runner.js",
32
+ encoding: 'UTF-8'
33
+ )
34
+
28
35
  JavaScriptCore = ExternalRuntime.new(
29
36
  name: "JavaScriptCore",
30
- command: "/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc",
37
+ command: [
38
+ "/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc",
39
+ "/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc",
40
+ ],
31
41
  runner_path: ExecJS.root + "/support/jsc_runner.js"
32
42
  )
33
43
 
@@ -64,7 +74,9 @@ module ExecJS
64
74
  end
65
75
 
66
76
  def self.from_environment
67
- if name = ENV["EXECJS_RUNTIME"]
77
+ env = ENV["EXECJS_RUNTIME"]
78
+ if env && !env.empty?
79
+ name = env
68
80
  raise RuntimeUnavailable, "#{name} runtime is not defined" unless const_defined?(name)
69
81
  runtime = const_get(name)
70
82
 
@@ -79,10 +91,11 @@ module ExecJS
79
91
 
80
92
  def self.runtimes
81
93
  @runtimes ||= [
82
- RubyRacer,
83
94
  RubyRhino,
95
+ GraalJS,
84
96
  Duktape,
85
97
  MiniRacer,
98
+ Bun,
86
99
  Node,
87
100
  JavaScriptCore,
88
101
  SpiderMonkey,
@@ -0,0 +1,29 @@
1
+ (function(program, execJS) { (function() {execJS(program) }).call({}); })(function(self, global, process, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source}
2
+ }, function(program) {
3
+ // Force BunJS to use sloppy mode see https://github.com/oven-sh/bun/issues/4527#issuecomment-1709520894
4
+ exports.abc = function(){}
5
+ var __process__ = process;
6
+ var printFinal = function(string) {
7
+ process.stdout.write('' + string, function() {
8
+ __process__.exit(0);
9
+ });
10
+ };
11
+ try {
12
+ delete this.process;
13
+ delete this.console;
14
+ result = program();
15
+ process = __process__;
16
+ if (typeof result == 'undefined' && result !== null) {
17
+ printFinal('["ok"]');
18
+ } else {
19
+ try {
20
+ printFinal(JSON.stringify(['ok', result]));
21
+ } catch (err) {
22
+ printFinal(JSON.stringify(['err', '' + err, err.stack]));
23
+ }
24
+ }
25
+ } catch (err) {
26
+ process = __process__;
27
+ printFinal(JSON.stringify(['err', '' + err, err.stack]));
28
+ }
29
+ });
@@ -2,6 +2,14 @@
2
2
  }, function(program) {
3
3
  var output;
4
4
  try {
5
+ delete this.console;
6
+ delete this.setTimeout;
7
+ delete this.setInterval;
8
+ delete this.clearTimeout;
9
+ delete this.clearInterval;
10
+ delete this.setImmediate;
11
+ delete this.clearImmediate;
12
+
5
13
  result = program();
6
14
  if (typeof result == 'undefined' && result !== null) {
7
15
  print('["ok"]');
@@ -1,20 +1,34 @@
1
- (function(program, execJS) { execJS(program) })(function(global, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source}
1
+ (function(program, execJS) { execJS(program) })(function(global, process, module, exports, require, console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source}
2
2
  }, function(program) {
3
- var output, print = function(string) {
4
- process.stdout.write('' + string);
3
+ var __process__ = process;
4
+
5
+ var printFinal = function(string) {
6
+ process.stdout.write('' + string, function() {
7
+ __process__.exit(0);
8
+ });
5
9
  };
6
10
  try {
11
+ delete this.process;
12
+ delete this.console;
13
+ delete this.setTimeout;
14
+ delete this.setInterval;
15
+ delete this.clearTimeout;
16
+ delete this.clearInterval;
17
+ delete this.setImmediate;
18
+ delete this.clearImmediate;
7
19
  result = program();
20
+ this.process = __process__;
8
21
  if (typeof result == 'undefined' && result !== null) {
9
- print('["ok"]');
22
+ printFinal('["ok"]');
10
23
  } else {
11
24
  try {
12
- print(JSON.stringify(['ok', result]));
25
+ printFinal(JSON.stringify(['ok', result]));
13
26
  } catch (err) {
14
- print(JSON.stringify(['err', '' + err, err.stack]));
27
+ printFinal(JSON.stringify(['err', '' + err, err.stack]));
15
28
  }
16
29
  }
17
30
  } catch (err) {
18
- print(JSON.stringify(['err', '' + err, err.stack]));
31
+ this.process = __process__;
32
+ printFinal(JSON.stringify(['err', '' + err, err.stack]));
19
33
  }
20
34
  });
@@ -1,7 +1,14 @@
1
- (function(program, execJS) { execJS(program) })(function() { #{source}
1
+ (function(program, execJS) { execJS(program) })(function(console, setTimeout, setInterval, clearTimeout, clearInterval, setImmediate, clearImmediate) { #{source}
2
2
  }, function(program) {
3
3
  var output;
4
4
  try {
5
+ delete this.console;
6
+ delete this.setTimeout;
7
+ delete this.setInterval;
8
+ delete this.clearTimeout;
9
+ delete this.clearInterval;
10
+ delete this.setImmediate;
11
+ delete this.clearImmediate;
5
12
  result = program();
6
13
  if (typeof result == 'undefined' && result !== null) {
7
14
  print('["ok"]');
@@ -1,3 +1,3 @@
1
1
  module ExecJS
2
- VERSION = "2.7.0"
2
+ VERSION = "2.9.1"
3
3
  end
metadata CHANGED
@@ -1,15 +1,15 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: execjs
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.7.0
4
+ version: 2.9.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Sam Stephenson
8
8
  - Josh Peek
9
- autorequire:
9
+ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-05-20 00:00:00.000000000 Z
12
+ date: 2023-09-16 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rake
@@ -38,14 +38,14 @@ files:
38
38
  - lib/execjs.rb
39
39
  - lib/execjs/disabled_runtime.rb
40
40
  - lib/execjs/duktape_runtime.rb
41
- - lib/execjs/encoding.rb
42
41
  - lib/execjs/external_runtime.rb
42
+ - lib/execjs/graaljs_runtime.rb
43
43
  - lib/execjs/mini_racer_runtime.rb
44
44
  - lib/execjs/module.rb
45
- - lib/execjs/ruby_racer_runtime.rb
46
45
  - lib/execjs/ruby_rhino_runtime.rb
47
46
  - lib/execjs/runtime.rb
48
47
  - lib/execjs/runtimes.rb
48
+ - lib/execjs/support/bun_runner.js
49
49
  - lib/execjs/support/jsc_runner.js
50
50
  - lib/execjs/support/jscript_runner.js
51
51
  - lib/execjs/support/json2.js
@@ -57,7 +57,7 @@ homepage: https://github.com/rails/execjs
57
57
  licenses:
58
58
  - MIT
59
59
  metadata: {}
60
- post_install_message:
60
+ post_install_message:
61
61
  rdoc_options: []
62
62
  require_paths:
63
63
  - lib
@@ -65,16 +65,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
- version: 1.9.3
68
+ version: 2.5.0
69
69
  required_rubygems_version: !ruby/object:Gem::Requirement
70
70
  requirements:
71
71
  - - ">="
72
72
  - !ruby/object:Gem::Version
73
73
  version: '0'
74
74
  requirements: []
75
- rubyforge_project:
76
- rubygems_version: 2.5.1
77
- signing_key:
75
+ rubygems_version: 3.3.7
76
+ signing_key:
78
77
  specification_version: 4
79
78
  summary: Run JavaScript code from Ruby
80
79
  test_files: []
@@ -1,26 +0,0 @@
1
- module ExecJS
2
- # Encodes strings as UTF-8
3
- module Encoding
4
- if RUBY_ENGINE == 'jruby' || RUBY_ENGINE == 'rbx'
5
- # workaround for jruby bug http://jira.codehaus.org/browse/JRUBY-6588
6
- # workaround for rbx bug https://github.com/rubinius/rubinius/issues/1729
7
- def encode(string)
8
- if string.encoding.name == 'ASCII-8BIT'
9
- data = string.dup
10
- data.force_encoding('UTF-8')
11
-
12
- unless data.valid_encoding?
13
- raise ::Encoding::UndefinedConversionError, "Could not encode ASCII-8BIT data #{string.dump} as UTF-8"
14
- end
15
- else
16
- data = string.encode('UTF-8')
17
- end
18
- data
19
- end
20
- else
21
- def encode(string)
22
- string.encode('UTF-8')
23
- end
24
- end
25
- end
26
- end
@@ -1,114 +0,0 @@
1
- require "execjs/runtime"
2
-
3
- module ExecJS
4
- class RubyRacerRuntime < Runtime
5
- class Context < Runtime::Context
6
- def initialize(runtime, source = "", options = {})
7
- source = encode(source)
8
-
9
- lock do
10
- @v8_context = ::V8::Context.new
11
-
12
- begin
13
- @v8_context.eval(source)
14
- rescue ::V8::JSError => e
15
- raise wrap_error(e)
16
- end
17
- end
18
- end
19
-
20
- def exec(source, options = {})
21
- source = encode(source)
22
-
23
- if /\S/ =~ source
24
- eval "(function(){#{source}})()", options
25
- end
26
- end
27
-
28
- def eval(source, options = {})
29
- source = encode(source)
30
-
31
- if /\S/ =~ source
32
- lock do
33
- begin
34
- unbox @v8_context.eval("(#{source})")
35
- rescue ::V8::JSError => e
36
- raise wrap_error(e)
37
- end
38
- end
39
- end
40
- end
41
-
42
- def call(properties, *args)
43
- lock do
44
- begin
45
- unbox @v8_context.eval(properties).call(*args)
46
- rescue ::V8::JSError => e
47
- raise wrap_error(e)
48
- end
49
- end
50
- end
51
-
52
- def unbox(value)
53
- case value
54
- when ::V8::Function
55
- nil
56
- when ::V8::Array
57
- value.map { |v| unbox(v) }
58
- when ::V8::Object
59
- value.inject({}) do |vs, (k, v)|
60
- vs[k] = unbox(v) unless v.is_a?(::V8::Function)
61
- vs
62
- end
63
- when String
64
- value.force_encoding('UTF-8')
65
- else
66
- value
67
- end
68
- end
69
-
70
- private
71
- def lock
72
- result, exception = nil, nil
73
- V8::C::Locker() do
74
- begin
75
- result = yield
76
- rescue Exception => e
77
- exception = e
78
- end
79
- end
80
-
81
- if exception
82
- raise exception
83
- else
84
- result
85
- end
86
- end
87
-
88
- def wrap_error(e)
89
- error_class = e.value["name"] == "SyntaxError" ? RuntimeError : ProgramError
90
-
91
- stack = e.value["stack"] || ""
92
- stack = stack.split("\n")
93
- stack.shift
94
- stack = [e.message[/<eval>:\d+:\d+/, 0]].compact if stack.empty?
95
- stack = stack.map { |line| line.sub(" at ", "").sub("<eval>", "(execjs)").strip }
96
-
97
- error = error_class.new(e.value.to_s)
98
- error.set_backtrace(stack + caller)
99
- error
100
- end
101
- end
102
-
103
- def name
104
- "therubyracer (V8)"
105
- end
106
-
107
- def available?
108
- require "v8"
109
- true
110
- rescue LoadError
111
- false
112
- end
113
- end
114
- end