execjs 2.8.1 → 2.9.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +3 -1
- data/lib/execjs/duktape_runtime.rb +3 -3
- data/lib/execjs/external_runtime.rb +13 -15
- data/lib/execjs/graaljs_runtime.rb +147 -0
- data/lib/execjs/mini_racer_runtime.rb +3 -3
- data/lib/execjs/ruby_rhino_runtime.rb +9 -4
- data/lib/execjs/runtime.rb +0 -4
- data/lib/execjs/runtimes.rb +12 -0
- data/lib/execjs/support/bun_runner.js +29 -0
- data/lib/execjs/support/jsc_runner.js +7 -0
- data/lib/execjs/support/v8_runner.js +8 -1
- data/lib/execjs/version.rb +1 -1
- metadata +5 -4
- data/lib/execjs/encoding.rb +0 -26
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 62270ddc7b87cd04ea4c4c652a0a58a22b067051a07e31c2f48b05246566bfbc
|
4
|
+
data.tar.gz: b5ba2f65f36600db563faeb4e526e67f01927879d239e16e96e4861fa83121da
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 79e1992e371a9e182eed6aaa4b0efef15db4909f44cd981a701c83f954a9e0b7a59fb1459e5a9b332d2cd3f0f8aa3f9273789badfefe89fe5f3bcfc918d02c50
|
7
|
+
data.tar.gz: aec6e50425979484e5913f5c64c3acb1417a1ac2c72659f01defec23704bee3a0be558800fd486df1bb8eb575b0daa7b86cd15bcbfd04c1242b400fe37f70667
|
data/README.md
CHANGED
@@ -11,11 +11,13 @@ ExecJS supports these runtimes:
|
|
11
11
|
Rhino embedded within JRuby
|
12
12
|
* [Duktape.rb](https://github.com/judofyr/duktape.rb) - Duktape JavaScript interpreter
|
13
13
|
* [Node.js](http://nodejs.org/)
|
14
|
+
* [Bun.sh](https://bun.sh) - JavaScript runtime & toolkit designed for speed
|
14
15
|
* Apple JavaScriptCore - Included with Mac OS X
|
15
16
|
* [Microsoft Windows Script Host](http://msdn.microsoft.com/en-us/library/9bbdkx3k.aspx) (JScript)
|
16
17
|
* [Google V8](http://code.google.com/p/v8/)
|
17
|
-
* [mini_racer](https://github.com/
|
18
|
+
* [mini_racer](https://github.com/rubyjs/mini_racer) - Google V8
|
18
19
|
embedded within Ruby
|
20
|
+
* [GraalVM JavaScript](https://www.graalvm.org/javascript/) - used on TruffleRuby
|
19
21
|
|
20
22
|
A short example:
|
21
23
|
|
@@ -6,21 +6,21 @@ 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(
|
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(
|
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(
|
23
|
+
@ctx.eval_string("(#{source.encode(Encoding::UTF_8)})", '(execjs)')
|
24
24
|
rescue Exception => e
|
25
25
|
raise wrap_error(e)
|
26
26
|
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(
|
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(
|
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(
|
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
|
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")
|
@@ -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,7 +4,7 @@ module ExecJS
|
|
4
4
|
class MiniRacerRuntime < Runtime
|
5
5
|
class Context < Runtime::Context
|
6
6
|
def initialize(runtime, source = "", options={})
|
7
|
-
source = encode(
|
7
|
+
source = source.encode(Encoding::UTF_8)
|
8
8
|
@context = ::MiniRacer::Context.new
|
9
9
|
@context.eval("delete this.console");
|
10
10
|
translate do
|
@@ -13,7 +13,7 @@ module ExecJS
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def exec(source, options = {})
|
16
|
-
source = encode(
|
16
|
+
source = source.encode(Encoding::UTF_8)
|
17
17
|
|
18
18
|
if /\S/ =~ source
|
19
19
|
eval "(function(){#{source}})()"
|
@@ -21,7 +21,7 @@ module ExecJS
|
|
21
21
|
end
|
22
22
|
|
23
23
|
def eval(source, options = {})
|
24
|
-
source = encode(
|
24
|
+
source = source.encode(Encoding::UTF_8)
|
25
25
|
|
26
26
|
if /\S/ =~ source
|
27
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(
|
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(
|
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(
|
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
|
-
|
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
|
data/lib/execjs/runtime.rb
CHANGED
data/lib/execjs/runtimes.rb
CHANGED
@@ -4,6 +4,7 @@ require "execjs/duktape_runtime"
|
|
4
4
|
require "execjs/external_runtime"
|
5
5
|
require "execjs/ruby_rhino_runtime"
|
6
6
|
require "execjs/mini_racer_runtime"
|
7
|
+
require "execjs/graaljs_runtime"
|
7
8
|
|
8
9
|
module ExecJS
|
9
10
|
module Runtimes
|
@@ -13,6 +14,8 @@ module ExecJS
|
|
13
14
|
|
14
15
|
RubyRhino = RubyRhinoRuntime.new
|
15
16
|
|
17
|
+
GraalJS = GraalJSRuntime.new
|
18
|
+
|
16
19
|
MiniRacer = MiniRacerRuntime.new
|
17
20
|
|
18
21
|
Node = ExternalRuntime.new(
|
@@ -22,6 +25,13 @@ module ExecJS
|
|
22
25
|
encoding: 'UTF-8'
|
23
26
|
)
|
24
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
|
+
|
25
35
|
JavaScriptCore = ExternalRuntime.new(
|
26
36
|
name: "JavaScriptCore",
|
27
37
|
command: [
|
@@ -82,8 +92,10 @@ module ExecJS
|
|
82
92
|
def self.runtimes
|
83
93
|
@runtimes ||= [
|
84
94
|
RubyRhino,
|
95
|
+
GraalJS,
|
85
96
|
Duktape,
|
86
97
|
MiniRacer,
|
98
|
+
Bun,
|
87
99
|
Node,
|
88
100
|
JavaScriptCore,
|
89
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
|
+
});
|
@@ -3,6 +3,13 @@
|
|
3
3
|
var output;
|
4
4
|
try {
|
5
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
|
+
|
6
13
|
result = program();
|
7
14
|
if (typeof result == 'undefined' && result !== null) {
|
8
15
|
print('["ok"]');
|
@@ -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"]');
|
data/lib/execjs/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: execjs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.9.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Sam Stephenson
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2023-09-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rake
|
@@ -38,13 +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
45
|
- lib/execjs/ruby_rhino_runtime.rb
|
46
46
|
- lib/execjs/runtime.rb
|
47
47
|
- lib/execjs/runtimes.rb
|
48
|
+
- lib/execjs/support/bun_runner.js
|
48
49
|
- lib/execjs/support/jsc_runner.js
|
49
50
|
- lib/execjs/support/jscript_runner.js
|
50
51
|
- lib/execjs/support/json2.js
|
@@ -71,7 +72,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
71
72
|
- !ruby/object:Gem::Version
|
72
73
|
version: '0'
|
73
74
|
requirements: []
|
74
|
-
rubygems_version: 3.
|
75
|
+
rubygems_version: 3.3.7
|
75
76
|
signing_key:
|
76
77
|
specification_version: 4
|
77
78
|
summary: Run JavaScript code from Ruby
|
data/lib/execjs/encoding.rb
DELETED
@@ -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
|