execjs 2.5.2 → 2.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 +5 -5
- data/{LICENSE → MIT-LICENSE} +2 -2
- data/README.md +9 -6
- data/lib/execjs/disabled_runtime.rb +3 -3
- data/lib/execjs/duktape_runtime.rb +3 -2
- data/lib/execjs/external_runtime.rb +21 -16
- data/lib/execjs/mini_racer_runtime.rb +103 -0
- data/lib/execjs/module.rb +6 -6
- data/lib/execjs/ruby_rhino_runtime.rb +1 -1
- data/lib/execjs/runtime.rb +39 -10
- data/lib/execjs/runtimes.rb +23 -10
- data/lib/execjs/support/jsc_runner.js +1 -0
- data/lib/execjs/support/node_runner.js +13 -1
- data/lib/execjs/support/v8_runner.js +18 -0
- data/lib/execjs/version.rb +1 -1
- metadata +9 -9
- data/lib/execjs/ruby_racer_runtime.rb +0 -114
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
|
-
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: d8d9f5aa1c15a7f78fd46fac3e22c3341a196d4cf82212cbc37669bd49daa2a4
|
4
|
+
data.tar.gz: 4b720a645a2d68adbd09d7e9111b12e8034c4f038738a7fe2d7b1be928d80002
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2388cc21b50bc84c26546c5e2ecd5be158f712e77fb3d505bc5b61d8fa292cc9a82796c2c25c56181a6cd84b6f9e09af7950648e0eacf3421e5a88fccab60d6d
|
7
|
+
data.tar.gz: c761477dff8eaeba2534175722b4ea0f386499a5a524ae202bd5310c230d861f4bcf6efd4b489b63f7958756615b6cd56d2128805ca239d98abf7894d98b1223
|
data/{LICENSE → MIT-LICENSE}
RENAMED
@@ -1,5 +1,5 @@
|
|
1
|
-
Copyright (c) 2015 Sam Stephenson
|
2
|
-
Copyright (c) 2015 Josh Peek
|
1
|
+
Copyright (c) 2015-2016 Sam Stephenson
|
2
|
+
Copyright (c) 2015-2016 Josh Peek
|
3
3
|
|
4
4
|
Permission is hereby granted, free of charge, to any person obtaining
|
5
5
|
a copy of this software and associated documentation files (the
|
data/README.md
CHANGED
@@ -7,14 +7,15 @@ 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/)
|
16
14
|
* Apple JavaScriptCore - Included with Mac OS X
|
17
15
|
* [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) (JScript)
|
16
|
+
* [Google V8](http://code.google.com/p/v8/)
|
17
|
+
* [mini_racer](https://github.com/discourse/mini_racer) - Google V8
|
18
|
+
embedded within Ruby
|
18
19
|
|
19
20
|
A short example:
|
20
21
|
|
@@ -42,7 +43,6 @@ context.call("CoffeeScript.compile", "square = (x) -> x * x", bare: true)
|
|
42
43
|
$ gem install execjs
|
43
44
|
```
|
44
45
|
|
45
|
-
|
46
46
|
# FAQ
|
47
47
|
|
48
48
|
**Why can't I use CommonJS `require()` inside ExecJS?**
|
@@ -72,9 +72,12 @@ are automatically detected, each runtime has different sandboxing properties.
|
|
72
72
|
You shouldn't use `ExecJS.eval` on any inputs you wouldn't feel comfortable Ruby
|
73
73
|
`eval()`ing.
|
74
74
|
|
75
|
+
## Contributing to ExecJS
|
75
76
|
|
76
|
-
|
77
|
+
ExecJS is work of dozens of contributors. You're encouraged to submit pull requests, propose
|
78
|
+
features and discuss issues.
|
77
79
|
|
78
|
-
|
80
|
+
See [CONTRIBUTING](CONTRIBUTING.md).
|
79
81
|
|
80
|
-
|
82
|
+
## License
|
83
|
+
ExecJS is released under the [MIT License](MIT-LICENSE).
|
@@ -6,15 +6,15 @@ module ExecJS
|
|
6
6
|
"Disabled"
|
7
7
|
end
|
8
8
|
|
9
|
-
def exec(source)
|
9
|
+
def exec(source, options = {})
|
10
10
|
raise Error, "ExecJS disabled"
|
11
11
|
end
|
12
12
|
|
13
|
-
def eval(source)
|
13
|
+
def eval(source, options = {})
|
14
14
|
raise Error, "ExecJS disabled"
|
15
15
|
end
|
16
16
|
|
17
|
-
def compile(source)
|
17
|
+
def compile(source, options = {})
|
18
18
|
raise Error, "ExecJS disabled"
|
19
19
|
end
|
20
20
|
|
@@ -4,7 +4,7 @@ require "json"
|
|
4
4
|
module ExecJS
|
5
5
|
class DuktapeRuntime < Runtime
|
6
6
|
class Context < Runtime::Context
|
7
|
-
def initialize(runtime, source = "")
|
7
|
+
def initialize(runtime, source = "", options = {})
|
8
8
|
@ctx = Duktape::Context.new(complex_object: nil)
|
9
9
|
@ctx.exec_string(encode(source), '(execjs)')
|
10
10
|
rescue Exception => e
|
@@ -26,7 +26,8 @@ module ExecJS
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def call(identifier, *args)
|
29
|
-
@ctx.
|
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
|
@@ -4,7 +4,7 @@ require "execjs/runtime"
|
|
4
4
|
module ExecJS
|
5
5
|
class ExternalRuntime < Runtime
|
6
6
|
class Context < Runtime::Context
|
7
|
-
def initialize(runtime, source = "")
|
7
|
+
def initialize(runtime, source = "", options = {})
|
8
8
|
source = encode(source)
|
9
9
|
|
10
10
|
@runtime = runtime
|
@@ -120,20 +120,25 @@ module ExecJS
|
|
120
120
|
@binary ||= which(@command)
|
121
121
|
end
|
122
122
|
|
123
|
-
def locate_executable(
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
if File.executable? cmd
|
129
|
-
cmd
|
130
|
-
else
|
131
|
-
path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |p|
|
132
|
-
full_path = File.join(p, cmd)
|
133
|
-
File.executable?(full_path) && File.file?(full_path)
|
123
|
+
def locate_executable(command)
|
124
|
+
commands = Array(command)
|
125
|
+
if ExecJS.windows? && File.extname(command) == ""
|
126
|
+
ENV['PATHEXT'].split(File::PATH_SEPARATOR).each { |p|
|
127
|
+
commands << (command + p)
|
134
128
|
}
|
135
|
-
path && File.expand_path(cmd, path)
|
136
129
|
end
|
130
|
+
|
131
|
+
commands.find { |cmd|
|
132
|
+
if File.executable? cmd
|
133
|
+
cmd
|
134
|
+
else
|
135
|
+
path = ENV['PATH'].split(File::PATH_SEPARATOR).find { |p|
|
136
|
+
full_path = File.join(p, cmd)
|
137
|
+
File.executable?(full_path) && File.file?(full_path)
|
138
|
+
}
|
139
|
+
path && File.expand_path(cmd, path)
|
140
|
+
end
|
141
|
+
}
|
137
142
|
end
|
138
143
|
|
139
144
|
protected
|
@@ -168,7 +173,7 @@ module ExecJS
|
|
168
173
|
begin
|
169
174
|
command = binary.split(" ") << filename
|
170
175
|
`#{shell_escape(*command)} 2>&1 > #{path}`
|
171
|
-
output = File.open(path, 'rb',
|
176
|
+
output = File.open(path, 'rb', **@popen_options) { |f| f.read }
|
172
177
|
ensure
|
173
178
|
File.unlink(path) if path
|
174
179
|
end
|
@@ -192,7 +197,7 @@ module ExecJS
|
|
192
197
|
|
193
198
|
def exec_runtime(filename)
|
194
199
|
command = "#{Shellwords.join(binary.split(' ') << filename)} 2>&1"
|
195
|
-
io = IO.popen(command,
|
200
|
+
io = IO.popen(command, **@popen_options)
|
196
201
|
output = io.read
|
197
202
|
io.close
|
198
203
|
|
@@ -204,7 +209,7 @@ module ExecJS
|
|
204
209
|
end
|
205
210
|
else
|
206
211
|
def exec_runtime(filename)
|
207
|
-
io = IO.popen(binary.split(' ') << filename, @popen_options.merge({err: [:child, :out]}))
|
212
|
+
io = IO.popen(binary.split(' ') << filename, **(@popen_options.merge({err: [:child, :out]})))
|
208
213
|
output = io.read
|
209
214
|
io.close
|
210
215
|
|
@@ -0,0 +1,103 @@
|
|
1
|
+
require "execjs/runtime"
|
2
|
+
|
3
|
+
module ExecJS
|
4
|
+
class MiniRacerRuntime < Runtime
|
5
|
+
class Context < Runtime::Context
|
6
|
+
def initialize(runtime, source = "", options={})
|
7
|
+
source = encode(source)
|
8
|
+
@context = ::MiniRacer::Context.new
|
9
|
+
@context.eval("delete this.console");
|
10
|
+
translate do
|
11
|
+
@context.eval(source)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def exec(source, options = {})
|
16
|
+
source = encode(source)
|
17
|
+
|
18
|
+
if /\S/ =~ source
|
19
|
+
eval "(function(){#{source}})()"
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def eval(source, options = {})
|
24
|
+
source = encode(source)
|
25
|
+
|
26
|
+
if /\S/ =~ source
|
27
|
+
translate do
|
28
|
+
@context.eval("(#{source})")
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def call(identifier, *args)
|
34
|
+
# TODO optimise generate
|
35
|
+
eval "#{identifier}.apply(this, #{::JSON.generate(args)})"
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
def strip_functions!(value)
|
41
|
+
if Array === value
|
42
|
+
value.map! do |v|
|
43
|
+
if MiniRacer::JavaScriptFunction === value
|
44
|
+
nil
|
45
|
+
else
|
46
|
+
strip_functions!(v)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
elsif Hash === value
|
50
|
+
value.each do |k,v|
|
51
|
+
if MiniRacer::JavaScriptFunction === v
|
52
|
+
value.delete k
|
53
|
+
else
|
54
|
+
value[k] = strip_functions!(v)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
value
|
58
|
+
elsif MiniRacer::JavaScriptFunction === value
|
59
|
+
nil
|
60
|
+
else
|
61
|
+
value
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
def translate
|
66
|
+
begin
|
67
|
+
strip_functions! yield
|
68
|
+
rescue MiniRacer::RuntimeError => e
|
69
|
+
ex = ProgramError.new e.message
|
70
|
+
if backtrace = e.backtrace
|
71
|
+
backtrace = backtrace.map { |line|
|
72
|
+
if line =~ /JavaScript at/
|
73
|
+
line.sub("JavaScript at ", "")
|
74
|
+
.sub("<anonymous>", "(execjs)")
|
75
|
+
.strip
|
76
|
+
else
|
77
|
+
line
|
78
|
+
end
|
79
|
+
}
|
80
|
+
ex.set_backtrace backtrace
|
81
|
+
end
|
82
|
+
raise ex
|
83
|
+
rescue MiniRacer::ParseError => e
|
84
|
+
ex = RuntimeError.new e.message
|
85
|
+
ex.set_backtrace(["(execjs):1"] + e.backtrace)
|
86
|
+
raise ex
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|
91
|
+
|
92
|
+
def name
|
93
|
+
"mini_racer (V8)"
|
94
|
+
end
|
95
|
+
|
96
|
+
def available?
|
97
|
+
require "mini_racer"
|
98
|
+
true
|
99
|
+
rescue LoadError
|
100
|
+
false
|
101
|
+
end
|
102
|
+
end
|
103
|
+
end
|
data/lib/execjs/module.rb
CHANGED
@@ -15,16 +15,16 @@ module ExecJS
|
|
15
15
|
@runtime = runtime
|
16
16
|
end
|
17
17
|
|
18
|
-
def exec(source)
|
19
|
-
runtime.exec(source)
|
18
|
+
def exec(source, options = {})
|
19
|
+
runtime.exec(source, options)
|
20
20
|
end
|
21
21
|
|
22
|
-
def eval(source)
|
23
|
-
runtime.eval(source)
|
22
|
+
def eval(source, options = {})
|
23
|
+
runtime.eval(source, options)
|
24
24
|
end
|
25
25
|
|
26
|
-
def compile(source)
|
27
|
-
runtime.compile(source)
|
26
|
+
def compile(source, options = {})
|
27
|
+
runtime.compile(source, options)
|
28
28
|
end
|
29
29
|
|
30
30
|
def root
|
@@ -3,7 +3,7 @@ require "execjs/runtime"
|
|
3
3
|
module ExecJS
|
4
4
|
class RubyRhinoRuntime < Runtime
|
5
5
|
class Context < Runtime::Context
|
6
|
-
def initialize(runtime, source = "")
|
6
|
+
def initialize(runtime, source = "", options = {})
|
7
7
|
source = encode(source)
|
8
8
|
|
9
9
|
@rhino_context = ::Rhino::Context.new
|
data/lib/execjs/runtime.rb
CHANGED
@@ -6,18 +6,33 @@ module ExecJS
|
|
6
6
|
class Context
|
7
7
|
include Encoding
|
8
8
|
|
9
|
-
def initialize(runtime, source = "")
|
9
|
+
def initialize(runtime, source = "", options = {})
|
10
10
|
end
|
11
11
|
|
12
|
+
# Evaluates the +source+ in the context of a function body and returns the
|
13
|
+
# returned value.
|
14
|
+
#
|
15
|
+
# context.exec("return 1") # => 1
|
16
|
+
# context.exec("1") # => nil (nothing was returned)
|
12
17
|
def exec(source, options = {})
|
13
18
|
raise NotImplementedError
|
14
19
|
end
|
15
20
|
|
21
|
+
# Evaluates the +source+ as an expression and returns the result.
|
22
|
+
#
|
23
|
+
# context.eval("1") # => 1
|
24
|
+
# context.eval("return 1") # => Raises SyntaxError
|
16
25
|
def eval(source, options = {})
|
17
26
|
raise NotImplementedError
|
18
27
|
end
|
19
28
|
|
20
|
-
|
29
|
+
# Evaluates +source+ as an expression (which should be of type
|
30
|
+
# +function+), and calls the function with the given arguments.
|
31
|
+
# The function will be evaluated with the global object as +this+.
|
32
|
+
#
|
33
|
+
# context.call("function(a, b) { return a + b }", 1, 1) # => 2
|
34
|
+
# context.call("CoffeeScript.compile", "1 + 1")
|
35
|
+
def call(source, *args)
|
21
36
|
raise NotImplementedError
|
22
37
|
end
|
23
38
|
end
|
@@ -30,18 +45,32 @@ module ExecJS
|
|
30
45
|
self.class::Context
|
31
46
|
end
|
32
47
|
|
33
|
-
def exec(source)
|
34
|
-
context =
|
35
|
-
|
48
|
+
def exec(source, options = {})
|
49
|
+
context = compile("", options)
|
50
|
+
|
51
|
+
if context.method(:exec).arity == 1
|
52
|
+
context.exec(source)
|
53
|
+
else
|
54
|
+
context.exec(source, options)
|
55
|
+
end
|
36
56
|
end
|
37
57
|
|
38
|
-
def eval(source)
|
39
|
-
context =
|
40
|
-
|
58
|
+
def eval(source, options = {})
|
59
|
+
context = compile("", options)
|
60
|
+
|
61
|
+
if context.method(:eval).arity == 1
|
62
|
+
context.eval(source)
|
63
|
+
else
|
64
|
+
context.eval(source, options)
|
65
|
+
end
|
41
66
|
end
|
42
67
|
|
43
|
-
def compile(source)
|
44
|
-
context_class.
|
68
|
+
def compile(source, options = {})
|
69
|
+
if context_class.instance_method(:initialize).arity == 2
|
70
|
+
context_class.new(self, source)
|
71
|
+
else
|
72
|
+
context_class.new(self, source, options)
|
73
|
+
end
|
45
74
|
end
|
46
75
|
|
47
76
|
def deprecated?
|
data/lib/execjs/runtimes.rb
CHANGED
@@ -2,8 +2,8 @@ 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"
|
6
|
+
require "execjs/mini_racer_runtime"
|
7
7
|
|
8
8
|
module ExecJS
|
9
9
|
module Runtimes
|
@@ -11,20 +11,23 @@ module ExecJS
|
|
11
11
|
|
12
12
|
Duktape = DuktapeRuntime.new
|
13
13
|
|
14
|
-
RubyRacer = RubyRacerRuntime.new
|
15
|
-
|
16
14
|
RubyRhino = RubyRhinoRuntime.new
|
17
15
|
|
16
|
+
MiniRacer = MiniRacerRuntime.new
|
17
|
+
|
18
18
|
Node = ExternalRuntime.new(
|
19
19
|
name: "Node.js (V8)",
|
20
|
-
command: ["
|
20
|
+
command: ["node", "nodejs"],
|
21
21
|
runner_path: ExecJS.root + "/support/node_runner.js",
|
22
22
|
encoding: 'UTF-8'
|
23
23
|
)
|
24
24
|
|
25
25
|
JavaScriptCore = ExternalRuntime.new(
|
26
26
|
name: "JavaScriptCore",
|
27
|
-
command:
|
27
|
+
command: [
|
28
|
+
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/Current/Helpers/jsc",
|
29
|
+
"/System/Library/Frameworks/JavaScriptCore.framework/Versions/A/Resources/jsc",
|
30
|
+
],
|
28
31
|
runner_path: ExecJS.root + "/support/jsc_runner.js"
|
29
32
|
)
|
30
33
|
|
@@ -42,6 +45,13 @@ module ExecJS
|
|
42
45
|
encoding: 'UTF-16LE' # CScript with //U returns UTF-16LE
|
43
46
|
)
|
44
47
|
|
48
|
+
V8 = ExternalRuntime.new(
|
49
|
+
name: "V8",
|
50
|
+
command: "d8",
|
51
|
+
runner_path: ExecJS.root + "/support/v8_runner.js",
|
52
|
+
encoding: 'UTF-8'
|
53
|
+
)
|
54
|
+
|
45
55
|
|
46
56
|
def self.autodetect
|
47
57
|
from_environment || best_available ||
|
@@ -54,10 +64,12 @@ module ExecJS
|
|
54
64
|
end
|
55
65
|
|
56
66
|
def self.from_environment
|
57
|
-
|
67
|
+
env = ENV["EXECJS_RUNTIME"]
|
68
|
+
if env && !env.empty?
|
69
|
+
name = env
|
58
70
|
raise RuntimeUnavailable, "#{name} runtime is not defined" unless const_defined?(name)
|
59
71
|
runtime = const_get(name)
|
60
|
-
|
72
|
+
|
61
73
|
raise RuntimeUnavailable, "#{runtime.name} runtime is not available on this system" unless runtime.available?
|
62
74
|
runtime
|
63
75
|
end
|
@@ -69,13 +81,14 @@ module ExecJS
|
|
69
81
|
|
70
82
|
def self.runtimes
|
71
83
|
@runtimes ||= [
|
72
|
-
RubyRacer,
|
73
84
|
RubyRhino,
|
74
85
|
Duktape,
|
75
|
-
|
86
|
+
MiniRacer,
|
76
87
|
Node,
|
88
|
+
JavaScriptCore,
|
77
89
|
SpiderMonkey,
|
78
|
-
JScript
|
90
|
+
JScript,
|
91
|
+
V8
|
79
92
|
]
|
80
93
|
end
|
81
94
|
end
|
@@ -1,10 +1,20 @@
|
|
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
3
|
var output, print = function(string) {
|
4
4
|
process.stdout.write('' + string);
|
5
5
|
};
|
6
6
|
try {
|
7
|
+
var __process__ = process;
|
8
|
+
delete this.process;
|
9
|
+
delete this.console;
|
10
|
+
delete this.setTimeout;
|
11
|
+
delete this.setInterval;
|
12
|
+
delete this.clearTimeout;
|
13
|
+
delete this.clearInterval;
|
14
|
+
delete this.setImmediate;
|
15
|
+
delete this.clearImmediate;
|
7
16
|
result = program();
|
17
|
+
this.process = __process__;
|
8
18
|
if (typeof result == 'undefined' && result !== null) {
|
9
19
|
print('["ok"]');
|
10
20
|
} else {
|
@@ -15,6 +25,8 @@
|
|
15
25
|
}
|
16
26
|
}
|
17
27
|
} catch (err) {
|
28
|
+
this.process = __process__;
|
18
29
|
print(JSON.stringify(['err', '' + err, err.stack]));
|
19
30
|
}
|
31
|
+
__process__.exit(0);
|
20
32
|
});
|
@@ -0,0 +1,18 @@
|
|
1
|
+
(function(program, execJS) { execJS(program) })(function() { #{source}
|
2
|
+
}, function(program) {
|
3
|
+
var output;
|
4
|
+
try {
|
5
|
+
result = program();
|
6
|
+
if (typeof result == 'undefined' && result !== null) {
|
7
|
+
print('["ok"]');
|
8
|
+
} else {
|
9
|
+
try {
|
10
|
+
print(JSON.stringify(['ok', result]));
|
11
|
+
} catch (err) {
|
12
|
+
print(JSON.stringify(['err', '' + err, err.stack]));
|
13
|
+
}
|
14
|
+
}
|
15
|
+
} catch (err) {
|
16
|
+
print(JSON.stringify(['err', '' + err, err.stack]));
|
17
|
+
}
|
18
|
+
});
|
data/lib/execjs/version.rb
CHANGED
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.
|
4
|
+
version: 2.8.0
|
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:
|
12
|
+
date: 2021-05-10 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -33,15 +33,15 @@ executables: []
|
|
33
33
|
extensions: []
|
34
34
|
extra_rdoc_files: []
|
35
35
|
files:
|
36
|
-
- LICENSE
|
36
|
+
- MIT-LICENSE
|
37
37
|
- README.md
|
38
38
|
- lib/execjs.rb
|
39
39
|
- lib/execjs/disabled_runtime.rb
|
40
40
|
- lib/execjs/duktape_runtime.rb
|
41
41
|
- lib/execjs/encoding.rb
|
42
42
|
- lib/execjs/external_runtime.rb
|
43
|
+
- lib/execjs/mini_racer_runtime.rb
|
43
44
|
- lib/execjs/module.rb
|
44
|
-
- lib/execjs/ruby_racer_runtime.rb
|
45
45
|
- lib/execjs/ruby_rhino_runtime.rb
|
46
46
|
- lib/execjs/runtime.rb
|
47
47
|
- lib/execjs/runtimes.rb
|
@@ -50,12 +50,13 @@ files:
|
|
50
50
|
- lib/execjs/support/json2.js
|
51
51
|
- lib/execjs/support/node_runner.js
|
52
52
|
- lib/execjs/support/spidermonkey_runner.js
|
53
|
+
- lib/execjs/support/v8_runner.js
|
53
54
|
- lib/execjs/version.rb
|
54
55
|
homepage: https://github.com/rails/execjs
|
55
56
|
licenses:
|
56
57
|
- MIT
|
57
58
|
metadata: {}
|
58
|
-
post_install_message:
|
59
|
+
post_install_message:
|
59
60
|
rdoc_options: []
|
60
61
|
require_paths:
|
61
62
|
- lib
|
@@ -70,9 +71,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
70
71
|
- !ruby/object:Gem::Version
|
71
72
|
version: '0'
|
72
73
|
requirements: []
|
73
|
-
|
74
|
-
|
75
|
-
signing_key:
|
74
|
+
rubygems_version: 3.2.15
|
75
|
+
signing_key:
|
76
76
|
specification_version: 4
|
77
77
|
summary: Run JavaScript code from Ruby
|
78
78
|
test_files: []
|
@@ -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 = "")
|
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
|